52 votes

Comment déboguer le message "message sent to deallocated instance" dans Xcode 4 ?

J'ai appuyé alt + cmd + r et activé NSZombieEnabled dans Arguments > Variables d'environnement. En outre, je l'ai activé dans Diagnostics > Gestion de la mémoire > Activer les objets zombies.

Cependant, lorsque j'ai construit et exécuté l'application, à un moment donné, elle s'est plantée en affichant ce message inutile dans la console :

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

La trace de la pile est tout aussi inutile. J'ai déplacé le curseur du niveau de détail 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. Il est donc évident que NSZombiesEnabled ne fonctionne pas comme il le faisait dans Xcode 3, où il s'arrêtait sur l'objet mort.

Y a-t-il un moyen de savoir dont CALayer est désalloué trop tôt ?

Mise à jour : Après avoir construit et exécuté une centaine de fois de plus, le problème a soudainement DISPARU ! Il a complètement disparu ! Et la meilleure partie : Je n'ai modifié mon code d'aucune façon ! Entre temps, j'ai nettoyé le dossier de construction et le projet avec les commandes clean 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 il semble persistant. Heureusement, car je préfère trouver la cause première plutôt que d'ennuyer les utilisateurs au hasard.

Mise à jour 3 : Je l'ai finalement trouvé par accident :

startButton = newBttn;

aurait dû être :

self.startButton = newBttn;

startButton était une propriété de retenue et dans -dealloc je l'ai libérée. Il a donc été trop libéré et dans la plupart des cas (mais pas tous), après que la vue ait disparu, il s'est écrasé en donnant ce message bizarre CALayer retainCount.

L'instrument des zombies (CMD + I) a finalement indiqué que cela avait à voir avec un bouton. Mais il ne savait pas pourquoi ni où.

L'analyseur statique de Clang ne s'est pas plaint de ce problème évident.

102voto

Jeff Kelley Points 12893

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

58voto

chown Points 25161

En plus de l'excellente réponse de Jeff, pour faire presque la même chose, mais sans avoir à ouvrir Instruments ou à profiler votre application, vous pouvez définir les éléments suivants NSZombieEnabled , MallocStackLogging y garde malloc dans le débogueur. Ensuite, quand votre application se plante, 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 qui devrait vous aider à localiser la ligne exacte dans votre code qui cause le problème.

Cet article a quelques informations supplémentaires.

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