web-dev-qa-db-fra.com

Comment déboguer le "message envoyé à l'instance désallouée" dans Xcode4?

J'ai appuyé sur ALT + CMD + R et activé NSZombieEnabled dans Arguments> Variables d'environnement. De plus, je l'ai activé dans Diagnostics> Gestion de la mémoire> Activer les objets zombies.

Cependant, lorsque j'ai construit et exécuté, à un moment donné, mon application se bloque en me donnant ce message inutile dans la console:

*** -[CALayer retainCount]: message sent to deallocated instance 0x656b260

La trace de pile est tout aussi inutile. J'ai déplacé le curseur au niveau des détails complètement vers la droite. Le fil 1 me montre simplement ceci:

screenshot

Tout appartient au système et il n'y a pas une seule ligne liée à mon application. Donc, évidemment, NSZombiesEnabled ne fonctionne pas comme dans Xcode 3, où il s'est arrêté sur l'objet mort.

Existe-t-il un moyen de comprendre lequel CALayer est désalloué trop tôt?

Mise à jour: Donc, après avoir construit et exécuté environ 100 fois de plus, le problème A DISPARU! C'est complètement parti! Et la meilleure partie: je n'ai pas modifié mon code en aucune façon! Entre les deux, j'ai nettoyé le dossier de construction et le projet avec les commandes de nettoyage plusieurs fois et j'ai supprimé l'application dans le simulateur plusieurs fois également.

Mise à jour 2: Heureusement, le problème est réapparu. Et maintenant, cela semble persistant. Heureusement, parce que je préfère trouver la cause première plutôt que de déranger les utilisateurs au hasard.

Mise à jour 3: enfin trouvé par accident:

startButton = newBttn;

aurait du être:

self.startButton = newBttn;

startButton était une propriété de rétention et dans -dealloc je l'ai libérée. Donc, il a été surestimé et dans la plupart des cas (mais pas tous) après la disparition de la vue, il s'est écrasé, donnant ce message étrange de CALayer retentionCount.

L'instrument Zombies (CMD + I) a finalement souligné qu'il s'agissait d'un bouton. Je ne savais tout simplement pas pourquoi et où.

Clang Static Analyzer ne s'est pas plaint de ce problème évident.

49
dontWatchMyProfile

Si cela se reproduit, vous pouvez exécuter un instrument Zombies dédié. Appuyez sur Commande + I pour profiler l'application et sélectionnez l'instrument Zombies (vous devez être en cours d'exécution sur le simulateur). Si vous obtenez un zombie, vous pouvez afficher l'historique complet de la mémoire (chaque conservation/libération) pour cet objet, ce qui est extrêmement utile pour rechercher les erreurs.

98
Jeff Kelley

En plus de la grande réponse de Jeff; pour faire presque la même chose, mais sans avoir à ouvrir des instruments ou à profiler votre application, vous pouvez définir NSZombieEnabled , MallocStackLogging , et guard malloc in le débogueur. Ensuite, lorsque votre application se bloque, tapez ceci dans la console gdb:

(gdb) info malloc-history 0x543216

Remplacer 0x543216 avec l'adresse de l'objet qui a provoqué le crash, et vous obtiendrez une trace de pile beaucoup plus utile et cela devrait vous aider à localiser la ligne exacte de votre code qui cause le problème.

Cet article contient des informations supplémentaires.

53
chown