2011-10-13 14 views
7

Ho passato un po 'di tempo a eseguire il debug di un problema strano con ARC e le funzioni dealloc personalizzate.Problema di debugging Xcode e ARC (skipping dealloc)

  1. sto sottoclassi NSOperation classe
  2. ho impostato blocco completamento di questa operazione
  3. L'operazione fa riferimento un forte proprietà di molto oggetto piatto (nessun metodo, ivars automatici, due proprietà forti) chiamiamo questo oggetto DataRequest
  4. seguendo tutte le linee guida il blocco di completamento usa solo riferimenti deboli agli oggetti locali (inclusa l'operazione stessa)
  5. né compilatore né analizzatore ge nerate eventuali problemi
  6. DataRequest detiene il solo riferimento all'operazione che viene generata e viene distrutta nel blocco di completamento dell'operazione. È SEMPRE distrutto (il suo dealloc viene sempre eseguito)
  7. L'operazione ha una personalizzazione dealloc. Ho solo una singola chiamata NSLog in esso.

... e la questione è:

Se corro questo sotto nel debugger, il punto di interruzione nella dealloc non è mai colpito, non compare mai il messaggio di log. Principalmente pensavo che l'operazione perdesse.

Se eseguo questo strumento, tutto va bene, la console di sistema stampa il messaggio e lo strumento di allocazione segnala l'operazione che viene liberata dall'istantanea di stack corretta incluso il dealloc personalizzato. Nessuna perdita rilevata.

Sono sicuro al 100% che utilizzo le stesse impostazioni del compilatore per il debug e la profilazione.

La cosa più confusa alla fine: se creo una versione personalizzata di [DataRequest dealloc] e inserisco self.operation = nil; su di esso, tutto funziona correttamente anche dal debugger.

Qualcuno ha qualche suggerimento sulle opzioni del linker del compilatore per cercare di vedere qualche differenza? può essere un bug negli strumenti Apple (tutti noi eravamo nella posizione che incolpavano un grosso pesce per i nostri errori, giusto?)

... e sì, ho provato con GDB e LLDB. Il risultato è stato lo stesso - quello che potrebbe indicare qualcosa.

Ho cercato di creare un campione minimalista ma semplicemente lavorato (anzi);)

Grazie

+0

Ho fatto un'osservazione molto semplice ... se eseguo l'app sul simulatore da XCode (GDB o LLDB) i miei messaggi di log in 'dealloc' non vengono stampati. Se esco dal debugger e avvio l'app direttamente dal simulatore, Console.app mostra tutti i messaggi. No compilare nessun collegamento in mezzo. Strano. – simpleone

+0

... e un risultato ancora più semplice ... Se eseguo l'app da XCode in una sessione di debug, dealloc non viene chiamato (log non stampato) se eseguo l'app manualmente nel simulatore e quindi allego il debugger. tutto è come previsto – simpleone

risposta

7

Avete NSZombiesEnabled? Abbiamo avuto lo stesso problema e "risolto" disabilitando NSZombies.

"Prodotto" -> "schema" -> "schema Modifica" -> "Diagnostica" -> deselezionare "Enable Objects Zombie"

io non sono sicuro perché dealloc non viene chiamato quando NSZombies sono abilitati (Sono abbastanza sicuro che sia stato chiamato prima di ARC).

+0

Devo testare, ma sì, ho impostato NSZombiesEnabled. Sembra molto probabile - e almeno fornisce una spiegazione ragionevole per un comportamento diverso. – simpleone

+1

Posso confermare che NSZombiesEnabled sta causando il problema. Grazie molto! – simpleone

+1

Questo può accadere dappertutto quando si usa NSZombiesEnabled con ARC, non solo con 'NSOperation'. La cosa fondamentale se si osservano le stranezze di dealloc con ARC è di disabilitare NSZombiesEnabled (che è etichettato "Enabled Zombie Objects" nella scheda Edit Schemes ...> Diagnostics in Xcode 4.) –

1

Mi sono imbattuto nello stesso tipo di problema oggi e mi ci sono voluti circa 5 ore per scoprire che il problema era causato da NSZombies abilitato nelle impostazioni del mio progetto.

Sono anche d'accordo che prima di ARC, in questo caso è stato chiamato dealloc.

Dopo molti test sembra che dealloc non venga chiamato se si utilizza iOS 5.x (dispositivo o simulatore).

ma viene chiamato di nuovo (con Zombies abilitati) in iOS 6.x (dispositivo o simulatore)

Non so se questo cambiamento è causato da un bug in iOS5 che è stato patchato in iOS6, o una funzionalità introdotta e ripristinata.

Speranza che aiuta ...

0

Ho incontrato lo stesso tipo di problema oggi, ma il mio problema è stato un ciclo di mantenere generato da un blocco.

Se si sta utilizzando blocchi:

  1. Accertarsi sé non appaiono all'interno del blocco.
  2. Se è necessario utilizzare SELF all'interno di un blocco, utilizzare un riferimento debole.
  3. Assicurarsi che non vi siano macro all'interno del blocco che potrebbero fare riferimento a se stessi (come NSAssert).
Problemi correlati