2011-11-28 1 views
42

Ho premuto ALT + CMD + R e attivato NSZombieEnabled in Argomenti> Variabili di ambiente. Inoltre, l'ho attivato in Diagnostics> Memory Management> Enable Zombie Objects.Come eseguire il debug di "messaggio inviato all'istanza deallocata" in Xcode4?

Tuttavia, quando ho costruito e gestito, ad un certo punto i miei applicazione si blocca dandomi questo messaggio inutile nella console:

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

L'analisi dello stack è altrettanto inutile. Ho spostato il cursore del livello di dettagli completamente a destra. Discussione 1 mi mostra semplicemente questo:

screenshot

Tutto è di proprietà di sistema e non c'è una sola riga relativa alla mia app. Quindi, ovviamente, NSZombiesEnabled non funziona come in Xcode 3, dove si è fermato sull'oggetto morto.

C'è un modo per capire quale CALayer è deallocated troppo presto?

Aggiornamento: Quindi dopo aver costruito e avviato circa altre 100 volte, il problema è SCOMPARSO! È completamente sparito! E la parte migliore: non ho modificato il mio codice in alcun modo! Tra una e l'altra ho pulito la cartella build e ho eseguito il project con i comandi clean diverse volte e ho eliminato l'app nel simulatore diverse volte.

Aggiornamento 2: Fortunatamente il problema è riapparso. E ora sembra persistente. Fortunatamente, perché preferisco trovare la causa principale piuttosto che infastidire gli utenti a caso.

Update 3: Finalmente trovato per caso:

startButton = newBttn; 

avrebbe dovuto essere:

self.startButton = newBttn; 

startButton era una proprietà di fissaggio ed in -dealloc ho rilasciato. Quindi è stato rilasciato in modo eccessivo e nella maggior parte (ma non in tutti) i casi dopo che la vista è svanita si è schiantato dando quel strano messaggio di KeepCount di CALayer.

Lo strumento Zombi (CMD + I) ha infine sottolineato che ha a che fare con un pulsante. Non sapevo perché e dove.

Clang Static Analyzer non ha lamentato questo problema tecnico.

+0

Nessun bug solo "si fissa". Questo è molto probabilmente un problema di proprietà relativo alla concorrenza e molto probabilmente esiste ancora nel tuo codice. Una bomba a orologeria, se vuoi. Nei tuoi panni, darei un'occhiata molto seria a come sto gestendo le risorse basate su Core Animation ... – bbum

+0

Cosa intendi esattamente per risorse basate su Core Animation? – dontWatchMyProfile

+0

Tutto ciò che è relativo alla deposizione di gunk sullo schermo. Se si fa causa a cocos2d, è necessario rivedere la gestione delle risorse al suo interno mentre gestisce indirettamente le risorse CA *. – bbum

risposta

88

Se questo ricomincia, è possibile eseguire uno strumento dedicato Zombies. Premi Comando + I per profilare l'app e seleziona lo strumento Zombies (devi essere in esecuzione sul simulatore). Se si ottiene uno zombie, è possibile visualizzare l'intera cronologia della memoria (ogni mantenimento/rilascio) per quell'oggetto, che è estremamente utile per rintracciare gli errori.

+0

Ottimo strumento! Grazie! Anche se ora mostra una traccia di stack migliore, non riesco a capire quale UIView possegga quello zombie CALayer. Puoi indicare una buona risorsa che mostra come usare quello strumento in un caso come questo? – dontWatchMyProfile

+0

Grande, ottima risposta, grazie – Sam

+0

Questo ha reso la mia giornata. Non avevo idea che potessi profilare un'app in quel modo. Non hai idea di quanto sono felice adesso. – shulmey

46

In aggiunta alla grande risposta di Jeff; per fare quasi la stessa cosa, ma senza dover aprire Strumenti o profilare la tua app, puoi impostare NSZombieEnabled, MallocStackLogging e guard malloc nel debugger. Poi, quando la vostra applicazione si blocca, digitare questo nella console gdb:

(gdb) info malloc-history 0x543216 

Sostituire 0x543216 con l'indirizzo dell'oggetto che ha causato l'incidente, e si otterrà un molto più utile traccia dello stack e dovrebbe aiutare a individuare la riga esatta nel codice che causa il problema.

This article has some additional infoz.

+0

Penso che lo strumento Zombies sia fondamentalmente un wrapper della GUI attorno a questa procedura esatta - semplicemente gestisce alcuni dei lavori più complessi per te. – Olie

+12

Purtroppo questo non funziona con lldb – Chris

+20

FYI: Con il debugger LLDB si può fare questo come segue: (lldb) script di importazione lldb.macosx.heap (lldb) malloc_info --stack-storia 0x7c506a00 – Ron