Partager via


Nouveau système de comptage de références dans Xamarin.iOS

Xamarin.iOS 9.2.1 a introduit le système de comptage des références amélioré à toutes les applications par défaut. Il peut être utilisé pour éliminer de nombreux problèmes de mémoire qui étaient difficiles à suivre et à résoudre dans les versions antérieures de Xamarin.iOS.

Activation du nouveau système de comptage des références

À partir de Xamarin 9.2.1, le nouveau système de comptage de références est activé par défaut pour toutes les applications.

Si vous développez une application existante, vous pouvez case activée le fichier .csproj pour vous assurer que toutes les occurrences de MtouchUseRefCounting sont définies sur true, comme ci-dessous :

<MtouchUseRefCounting>true</MtouchUseRefCounting>

S’il est défini sur false votre application n’utilisera pas les nouveaux outils.

Utilisation d’anciennes versions de Xamarin

Xamarin.iOS 7.2.1 et versions ultérieures offre une préversion améliorée de notre nouveau système de comptage de références.

API classique :

Pour activer ce nouveau système de comptage de références, case activée la case à cocher Utiliser l’extension de comptage des références dans l’onglet Avancé des options de génération iOS de votre projet, comme indiqué ci-dessous :

Activer le nouveau système de comptage des références

Notez que ces options ont été supprimées dans les versions plus récentes de Visual Studio pour Mac.

API unifiée :

La nouvelle extension de comptage de références est requise pour l’API unifiée et doit être activée par défaut. Cette valeur n’est peut-être pas vérifiée automatiquement dans les versions antérieures de votre IDE et vous devrez peut-être placer une case activée par lui-même.

Important

Une version antérieure de cette fonctionnalité existe depuis MonoTouch 5.2, mais n’était disponible que pour sgen en tant que préversion expérimentale. Cette nouvelle version améliorée est désormais également disponible pour le garbage collector Boehm .

Historiquement, il existe deux types d’objets gérés par Xamarin.iOS : ceux qui n’étaient qu’un wrapper autour d’un objet natif (objets homologues) et ceux qui étendent ou incorporent de nouvelles fonctionnalités (objets dérivés), généralement en conservant un état supplémentaire en mémoire. Auparavant, il était possible que nous puissions augmenter un objet homologue avec l’état (par exemple, en ajoutant un gestionnaire d’événements C#), mais que nous laissons l’objet non référencé, puis collecté. Cela peut provoquer un blocage ultérieurement (par exemple, si le Objective-C runtime a été rappelé dans l’objet managé).

Le nouveau système met automatiquement à niveau les objets homologues en objets gérés par le runtime lorsqu’ils stockent des informations supplémentaires.

Cela résout les différents incidents qui se sont produits dans des situations telles que celle-ci :

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;
   }
}

Sans l’extension de nombre de références, ce code se bloquerait parce qu’il cell devient collectable, et donc son TouchDown délégué, ce qui se traduira par un pointeur pendant.

L’extension de nombre de références garantit que l’objet managé reste actif et empêche sa collection, à condition que l’objet natif soit conservé par du code natif.

Le nouveau système supprime également la nécessité d’utiliser la plupart des champs de stockage privés utilisés dans les liaisons, ce qui est l’approche par défaut pour maintenir instance en vie. L’éditeur de liens managé est suffisamment intelligent pour supprimer tous ces champs inutiles des applications à l’aide de la nouvelle extension de nombre de références.

Cela signifie que chaque instance d’objet managé consomme moins de mémoire qu’auparavant. Il résout également un problème connexe où certains champs de stockage contiennent des références qui n’étaient plus nécessaires par le runtime, ce qui rend difficile la Objective-C récupération de la mémoire.