Application iOS avec ARC, trouvez qui est le propriétaire d'un object

J'écris une application qui utilise ARC et qui semble avoir des memory leaks pour le moment. Google, j'ai trouvé quelques conseils sur la façon d'utiliser l'inspecteur. Dans là, je peux voir des tas d'allocations d'instances de certaines classs et je peux aussi voir une stack d'appels sur la façon dont l'object a été alloué et comment le count de retenue a été changé.

Mais il semble que je ne puisse pas voir la stack d'appels complète, donc je ne sais pas à qui appartient l'object à la fin. Il me semble que ce propriétaire ne libère en quelque sorte pas l'object (ou l'object qui possède l'object suspect).

Quelqu'un peut-il me donner un indice sur la search du propriétaire d'un object alloué?

S'il vous plaît noter également que les objects ne sont pas marqués comme "fuite", mais comme atsortingbué. Pour moi, il semble que les objects fuient car de nouveaux objects sont régulièrement atsortingbués.

Toute aide supplémentaire sur la meilleure façon de procéder et de find les fuites suspectées sont appréciées.

  1. En termes de la question académique de qui "possède" un object, c'est simplement celui qui maintient une strong reference à cet object.

  2. En termes de détection de fuites dans votre application, vous pouvez utiliser l'outil "Fuites" dans Instruments lorsque vous profilez l'application (choisissez "Profil" dans le menu "Produit" de Xcode).

  3. Si cela n'apparaît pas dans "Leaks", il semble que vous deviez alors décider s'il s'agit d'un cycle de reference fort (anciennement appelé cycle de rétention), d'une erreur logique simple (par exemple une reference circulaire dans les controllers de vue, des objects volumineux, etc.) ou un problème lié à la fondation de base (ARC n'assume la propriété que si vous utilisez CFBridgingRelease() ou __bridge_transfer ).

  4. En termes d'utilisation d'instruments pour find la source des allocations, les deux trucs qui m'aident le plus sont:

    • Cliquez en faisant glisser avec votre souris (dans les versions de Xcode antérieures à 6, vous devez maintenir la touche d' option pendant que vous faites cela) pour mettre en évidence une partie de la chronologie, pour identifier ce que vous voulez inspecter. Vous voulez probablement vous concentrer sur l'un de vos pics d'allocations. Par exemple, j'ai trouvé un bump dans mes allocations et l'ai mis en évidence en tant que tel (c'était un exemple ridiculement simple où je crée un tableau énorme dans viewDidLoad , mais j'espère que cela vous donne l'idée):

    entrez la description de l'image ici

    • Lorsque vous inspectez par tree d'appel, il est souvent utile de sélectionner "Masquer les bibliothèques système", pour se concentrer sur votre code. Et si vous double-click le nom de la méthode dans Instruments (dans mon exemple, ici, ce serait viewDidLoad ), Instruments vous montrera alors votre code qui fait l'allocation:

    entrez la description de l'image ici

    Vous pouvez ensuite double-cliquer sur la list des methods pertinentes et cela vous mènera précisément au code qui a fait l'atsortingbution.

    entrez la description de l'image ici

Bien que cela ne montre pas que la fuite a eu lieu (c'est-à-dire où le cycle de reference fort ou où vous ne l'avez pas libéré), ce type d'parsing peut souvent vous aider à déterminer où l'object a été instancié. étape pour dépister le problème.


Si vous devez vraiment déterminer qui possède un object (c'est-à-dire où les references fortes (ou les retenues) de l'object se sont produites), Xcode 8 dispose d'une nouvelle fonction de graphe d'object. Donc, déboguez l'application, puis appuyez sur l'icône "Debug Memory Graph" dans la barre de debugging (encerkey en rouge, ci-dessous). Une fois que vous faites cela, vous pouvez sélectionner un object sur la gauche et vous pouvez voir le graphique de l'object qui montre les revendications de propriété sur l'object:

entrez la description de l'image ici

Ce qui précède illustre le fait que l'image choisie a de fortes references à la fois par UIImageView dans lequel elle est présentée, mais aussi par le ViewController qui maintient également une reference forte.

Dans les versions antérieures de Xcode, établissez le profil de l'application pour qu'elle s'exécute dans Instruments et select l'option "Record reference counts". Dans Xcode 6, il se trouve dans l'onglet "Paramètres d'logging" du panneau le plus à droite:

entrez la description de l'image ici

Dans Xcode 5 et plus tôt, vous devez cliquer sur le je Cliquez sur le button info à côté de l'outil Allocations pour voir cette option "Enregistrer les references":

entrez la description de l'image ici

Quoi qu'il en soit, vous pouvez alors aller au Résumé des Allocations, explorer un object qui n'a pas été libéré, (en cliquant sur la flèche de droite flèche à côté de l'adresse de l'object lorsque vous regardez et object dans l'outil Allocations), puis vous verrez la list des retenues et des versions pour l'object en question, comme indiqué ci-dessus. Mais ceci ne sera capturé que si vous select le "Nombre de references d'logging" avant de profiler l'application.

Il faut un certain time pour s'habituer au suivi des counts de retenue de cette façon, mais si vous avez absolument besoin de savoir où les references fortes ont été établies, l'option «Enregistrer la reference count» peut vous aider.