Nový systém počítání odkazů v Xamarin.iOS

Xamarin.iOS 9.2.1 zavedl vylepšený systém počítání odkazů do všech aplikací ve výchozím nastavení. Dá se použít k odstranění mnoha problémů s pamětí, které byly obtížné sledovat a opravit v dřívějších verzích Xamarin.iOS.

Povolení nového systému počítání odkazů

Od Xamarinu 9.2.1 je nový systém počítání ref ve výchozím nastavení povolený pro všechny aplikace.

Pokud vyvíjíte existující aplikaci, můžete zkontrolovat soubor .csproj a ujistit se, že jsou všechny výskyty MtouchUseRefCounting nastavené na truenásledující:

<MtouchUseRefCounting>true</MtouchUseRefCounting>

Pokud je nastavená na false vaši aplikaci, nebude používat nové nástroje.

Použití starších verzí Xamarinu

Xamarin.iOS 7.2.1 a vyšší nabízí vylepšenou verzi Preview našeho nového systému pro počítání odkazů.

Klasické rozhraní API:

Pokud chcete povolit tento nový systém počítání odkazů, zaškrtněte políčko Použít rozšíření pro počítání odkazů, které najdete na kartě Upřesnit možnosti sestavení projektu pro iOS, jak je znázorněno níže:

Enable the new Reference Counting System

Upozorňujeme, že tyto možnosti byly odebrány v novějších verzích Visual Studio pro Mac.

Sjednocené rozhraní API:

Nové rozšíření pro počítání odkazů se vyžaduje pro sjednocené rozhraní API a mělo by být ve výchozím nastavení povolené. Starší verze integrovaného vývojového prostředí (IDE) nemusí mít tuto hodnotu zaškrtnutou automaticky a možná budete muset provést kontrolu sami.

Důležité

Starší verze této funkce už byla od Verze MonoTouch 5.2, ale byla k dispozici pouze pro sgen jako experimentální verze Preview. Tato nová rozšířená verze je nyní k dispozici také pro systém uvolňování paměti Boehm .

V minulosti existovaly dva druhy objektů spravovaných Xamarin.iOS: ty, které byly pouze obálkou kolem nativního objektu (peer objects) a těch, které rozšířily nebo začleňovaly nové funkce (odvozené objekty) – obvykle udržováním dodatečného stavu v paměti. Dříve bylo možné rozšířit partnerský objekt o stav (například přidáním obslužné rutiny události jazyka C#), ale nechat objekt neodkazovat a pak shromažďovat. To může způsobit chybové ukončení později (například pokud modul Objective-C runtime volal zpět do spravovaného objektu).

Nový systém automaticky upgraduje partnerské objekty na objekty spravované modulem runtime, když ukládají další informace.

To řeší různé chyby, ke kterým došlo v situacích, jako je tato:

class MyTableSource : UITableViewSource {
   public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) {
        var cell = tableView.DequeueReusableCell ("myId");
        if (cell != null)
                return cell;

        cell = new UITableViewCell (UITableViewCellStyle.Default, "myId");
        var txt = new UITextField ();
        txt.TouchDown += delegate { Console.WriteLine ("...."); };
        cell.ContentView.AddSubview (txt);
        return cell;
   }
}

Bez rozšíření počtu odkazů by se tento kód chybově ukončil, protože cell se stane collectible, a proto jeho TouchDown delegát, který se přeloží na dangling ukazatel.

Rozšíření počtu odkazů zajišťuje, že spravovaný objekt zůstane aktivní a zabrání jeho kolekci za předpokladu, že nativní objekt zůstane zachován nativním kódem.

Nový systém také eliminuje potřebu většiny privátních backingových polí používaných ve vazbách – což je výchozí přístup k udržování instance naživu. Spravovaný linker je dostatečně inteligentní, aby odebral všechna nepotřebná pole z aplikací pomocí nového rozšíření počtu odkazů.

To znamená, že každá instance spravovaných objektů spotřebovávají méně paměti než dříve. Řeší také související problém, kdy některá backingová pole budou obsahovat odkazy, které už Objective-C modul runtime nepotřebuje, a znesnadňuje uvolnění paměti.