34 votes

Est-il possible de "trouver le mystère retenu" ...?

Récemment, j'ai été la réparation de quelqu'un de code. Il y avait une grande classe qui ne serait pas dealloc. Vous auriez à le frapper avec 5 ou 6 versions de l'obtenir pour dealloc.

J'ai soigneusement regardé à travers la grande classe et a finalement trouvé les différentes choses qui devaient être libérés.

Cela m'a fait penser: il y a vraiment moyen facile de "trouver" tous les conserve sur un objet .. suis-je le droit?

Alors, est-il un moyen simple de "trouver tous les conserve" sur un objet? Est-il un bouton dans XCode ou des Instruments que tout le monde connaît?

Que faites-vous lorsque vous ne trouvez pas un mystère conserver comme ça?

Ainsi, dans l'iOS de l'univers, si quelqu'un connaît le "Spectacle où tous les conserve venus de sur cet objet" bouton -- merci!

P. S. Remarque qu'il n'y a pas de fuite, et cette question est totalement non liés à des fuites. L'objet, simplement "parfaitement bien". ne pas libération.


Plus tard ..

Vraiment étonnantes solution par Fabio:

Fabio a fourni une étonnante solution à ce problème. En neuf mots, elle est ici:

-(id)retain
    {
    NSLog(@"%@", [NSThread callStackSymbols]);
    return ([super retain]);
    }

C'est incroyablement utile dans de nombreuses situations, et conduit à beaucoup d'autres choses utiles. Vous avez probablement m'a sauvé deux semaines-homme de travail par an pour toujours, Fabio. Merci!

BTW, si vous êtes juste à se familiariser avec ce et aux prises avec la sortie, j'ai vu que, généralement, il y aura beaucoup de morceaux avec "UINib instantiateWithOwner:". Il ressemble à ceux viendra d'abord, la forte morceaux qui vont suivre.

72voto

Ben Clayton Points 16793

Instruments peut vous montrer la pile d'appel pour chaque malloc, la libération, et conservez-le pour toute l'Obj-C objet dans votre application sans modification de code requis. Il fonctionne lorsque vous utilisez un ARC, qui n'est pas le cas pour la solution de fabio.

C'est vraiment utile pour trouver ceux mystère conserve - par exemple, lorsqu'un objet ne sera pas le dealloc quand il le faut.

Voici comment:

  • CMD + I (Produit / Profil)
  • Lorsque les Instruments s'affiche, choisissez "Allocations" (PAS de Fuites)
  • Votre application doit s'exécuter.
  • Faire ce que les causes de votre mystère conserve à se produire.
  • Sélectionnez la "Répartition" de l'instrument sur le panneau de gauche.
  • Cliquez sur le petit bouton (i) pour afficher les options. Cochez le Dossier des comptes de référence " option. C'est important, ou seulement mallocs et libère sera enregistrée.
  • Dans la boîte de recherche en haut à droite, tapez le nom de votre classe (par exemple BCMyObject).
  • Cela permet de filtrer la liste des "Statistiques" pour montrer combien d'instances de la classe sont actuellement en ligne. La #vie colonne indique le nombre d'instances en direct.
  • Cliquez sur la ligne, puis la petite flèche -> à côté du nom de la classe. Vous verrez le fil d'ariane vous indique les Statistiques de l'Objet > > BCMyobject'
  • Cela vous montre toutes les instances de la classe dit.
  • Sélectionnez une instance, et cliquez sur la flèche à nouveau (cette fois en fonction de l'adresse)
  • Maintenant, vous allez voir les Statistiques de l'Objet > > BCMyObject > Historique " dans la breadcrumps.
  • Ce sera une liste de toutes les fois que l'objet est malloc avais conservé ou libéré.
  • Maintenant, en haut, sur la barre d'outils juste au-dessus de la Vue, de montrer la colonne de droite.
  • Sélectionnez l'une des lignes et vous verrez la pile d'appel complète qui a conduit à l'appel.

Facile! (ish)

22voto

Fabio Points 1429

Juste deviner ... mais vous pouvez écraser la méthode de conservation de la classe personnalisée appelant super et lancer un beau NSLog pour imprimer la pile d'appels.


Mise à jour avec le code actuel de Joe

 -(id) retain {
NSLog(@"%@", [NSThread callStackSymbols]);
return ([super retain]);
}
 

Un autre détail important est que [NSThread callStackSymbols] renvoie un tableau NSArray de NSString pouvant être filtré et utilisé à d'autres fins. Par exemple, dans le code complexe et dynamique, pour vérifier si une méthode en déclenche correctement une autre.

5voto

GorillaPatch Points 3445

Placez un point d'arrêt sur la coutume de la classe de conserver

Vous pouvez définir une symbolique point d'arrêt sur la retenir, puis réglez-la à retenir la méthode de la classe personnalisée. Le problème ici est que retenir est une méthode de NSObject vous aurez donc le choix de tous objective-c classes lors de la mise au point d'arrêt.

Dans ce cas, il serait préférable de remplacer le conserver méthode de la classe personnalisée avec un appel à super, donc il ne devrait pas faire quelque chose, mais vous pouvez ensuite placer un point d'arrêt à elle.

Utilisez un point d'arrêt à l'action pour le journal de l'appelant

Pour ajouter un point d'arrêt de l'action, double-cliquez sur le marqueur bleu. Trouver le point d'arrêt dans la liste et appuyez sur le bouton + à droite. Ensuite, choisissez Debugger command et ajouter la commande GDB frame 1 dans ce domaine, qui vous montrera l'appelant de la conserver. Par ce froid un journal de toutes les conserve et d'où ils viennent. Lors de l'enregistrement de l'communiqués d'une manière similaire, vous pouvez vérifier quelle est la version supplémentaire.

C'est toujours un peu fastidieux, mais c'est le meilleur je pense.

1voto

Joshua Nozzi Points 38718

Les instruments et leur gestion de la mémoire sont vos amis. Les fuites et les zombies sont deux des outils les plus précieux disponibles. Utilise les.

Produit -> Profil (ou Cmd-I)

1voto

tc. Points 23958

Il est, malheureusement, n'est pas facilement possible par programmation de déterminer ce qui est "propriétaire" d'un objet, puisque l'idée de "propriété d'objet" est une convention de codage (sauf si vous activez la collecte des ordures).

Pile de coupe est souvent utile (j'ai l'habitude d'utiliser quelques points d'arrêt avec bt;continue), mais qui ne vous raconte pas la fonction qui a appelé à retenir, pas de la "grande image" (par exemple, vous pourriez "transfert de propriété" avec [ivar2 release]; ivar2 = ivar1; ivar1 = nil;). Parfois, c'est un UIKit fuite de sorte que vous n'avez pas le code source et vous avez vraiment d'aller creuser.

Si ce n'est pas une fuite, toutefois, appelez - -release quelques fois et de voir où ça plante!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X