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 ve výchozím nastavení povolen nový systém počítání ref pro všechny aplikace.

Pokud vyvíjíte existující aplikaci, můžete zkontrolovat soubor .csproj, abyste měli jistotu, ž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í nemusí mít tuto hodnotu automaticky zaškrtnutou a možná budete muset provést kontrolu sami.

Důležité

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

Historicky existují dva druhy objektů spravovaných Xamarin.iOS: ty, které byly pouze obálkou nativního objektu (peer objekty) a těch, které rozšířily nebo zahrnovaly nové funkce (odvozené objekty) – obvykle zachováním dodatečného stavu v paměti. Dříve bylo možné, že bychom mohli rozšířit objekt partnerského vztahu se stavem (například přidáním obslužné rutiny události jazyka C#), ale že objekt necháme zrušit odvozování a následné shromažďování. To může způsobit chybové ukončení později (například pokud Objective-C se modul runtime volal zpět do spravovaného objektu).

Nový systém automaticky upgraduje partnerské objekty na objekty, které jsou spravovány modulem runtime při ukládání dalších informací.

Tím se vyřeší různé chybové ukončení, ke kterým došlo v situacích, jako je tento:

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čí, protože cell se stane shromážditelným, a proto TouchDown jeho 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é odebere potřebu většiny privátních backingových polí používaných v vazbách – což je výchozí přístup k udržování instance naživu. Spravovaný linker je dostatečně chytrý, 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řebujete, což znesnadňuje uvolnění paměti.