2012-04-04 12 views
16

Quindi eseguo il debug di un'app in preperation per la sua app in modo da rilasciare e ho attivato un punto di interruzione universale per "Tutte le eccezioni". Da allora, ogni volta che esegue l'applicazione, le stampe della console:Punto di interruzione che indica "objc_autoreleaseNoPool"

Catchpoint 2 (due) In attesa breakpoint 1 - "objc_exception_throw" risolto

objc [11765]: Oggetto 0x8f18ff0 di classe __NSCFLocale autoreleased senza piscina in posto - solo che perde - rompere l'objc_autoreleaseNoPool() per eseguire il debug

objc [11765]: oggetto 0x8f190a0 di classe __NSCFNumber autoreleased senza piscina in posto - solo che perde - rompere l'objc_autoreleaseNoPool() per eseguire il debug

objc [11765]: Oggetto 0x8f1fef0 di classe __NSCFLocale autoreleased senza piscina in posto - solo che perde - pausa objc_autoreleaseNoPool() per eseguire il debug

Letteralmente stampati 3 volte. Non ho idea di cosa significhi ma sembra male. Tutto il consiglio sarebbe apprezzato.

+0

hai una piscina autorelease? e controlla l'app per eventuali perdite con uno dei programmi di supporto che puoi trovare in xcode (profilo) – chikuba

+0

Non utilizzo alcun pool di autorelease. Sinceramente, non capisco perché ne useresti uno, quindi non l'ho mai fatto. Ma proverò che – Andrew

+0

Si presenta prima dell'app del. Finisce, ma ho commentato riga per riga l'intera faccenda, e sto ancora perdendo oggetti. Qualche pensiero? – Andrew

risposta

35

Nuova Info

ho deciso dove il mio problema sta creando un metodo autorelease swizzled.

Non consiglio di farlo se non si sa cosa si sta facendo, tuttavia questo è quello che ho scoperto.

+ (void) load; //Method is called outside the original autorelease pool. 
+ (void) initialize; // Method is called outside the original autorelease pool. 

NSThread crea il proprio thread, il metodo chiamato deve essere avvolto in una piscina autorelease.

Grand Central Dispatch si occupa dell'adattamento sul pool autorelease quando si utilizzano i comandi "dispatch _...". tuttavia, quando si invia manualmente. potresti volerlo avvolgere in un pool di autorelease.

Inoltre, ARC non gestisce il fatto di farvi sapere che un autorelease avverrà al di fuori di un pool.

Pertanto, se si sta utilizzando ARC e si è certi che si troverà al di fuori del pool autorelease. E non c'è nulla che tu possa fare al riguardo. Dovrai evitare tutti i metodi di convenienza.

utilizzare questo.

[[NSString alloc] initWithFormat:@"%@",myObject]; 

invece di questo

[NSString stringWithFormat:@"%@",myObject]; 

Ciò consentirà al sistema di arco di conservare e rilasciare, ma l'autorelease sottostante fatta con il metodo convenienza verranno saltate in quanto non sarà stato utilizzato il metodo di convenienza.

Spero che questo aiuti.

risposta originale

Ok, io non sento questa domanda è stato risposto con sufficiente dettaglio.

il messaggio che viene presentato è stato

objc[1310]: Object 0x34f720 of class SimpleKeychain autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug 

Il debugger sta indicando un possibile punto di interruzione che vi aiuterà a eseguire il debug la situazione. Ora, mentre questo punto di rottura ha davvero fatto ben poco per aiutare il debug della situazione. Penso che sia importante sapere come aggiungere quel breakpoint al debugger e così ho passato il tempo ad armeggiare con esso (dopo aver setacciato internet e non trovando nulla) fino a quando non sono riuscito a infrangere quell'errore.

È un po 'fastidioso che l'interruzione di tutti gli errori non lo catturi, ma qui ci sono i passaggi per aggiungere il breakpoint al debugger.

prima cosa che voglio fare è selezionare il navigatore punto di interruzione del debugger

navigator toolbar

cliccando su questa scheda

breakpoint button

prossimo si guarda verso la parte inferiore del riquadro di navigazione e premere il pulsante Più

Add Exception Breakpoint

Ciò consentirà di aggiungere manualmente un punto di interruzione.

Ho selezionato un punto di interruzione C++ e inserito il nome del messaggio nel campo di testo del nome.

Adding custom C++ exception

dopo l'aggiunta di questa eccezione ha fatto in realtà pausa.

Tuttavia questo può o non può essere utile a voi come uno sviluppatore oggettivo. Questo ha fatto irruzione nel codice Assembly.

assembly code at achieved breakpoint.

Purtroppo mostrato solo questo punto nello stack di chiamate per il thread.

Thread list

e si è scoperto che il problema era perché autorelease una classe chiamata autorelease in una chiamata dispatch_once. e ulteriori indagini hanno rivelato che il carico + (vuoto); il metodo sulla classe è stato chiamato prima di ogni altra cosa.questo viene fatto tramite la funzione call_load_methods ed è al di fuori della discussione sul metodo principale.

Error Call and Stack

per correggere questo, ho solo aggiunto la piscina autorelease wrapper per la chiamata.

updated error call

un'altra soluzione potrebbe essere quella di aggiungere il pool autorelease all'interno + carico (vuoto); metodo. ma questo era sufficiente per i miei usi.

NOTA: lo aggiungo al post qui perché non mi piace trovare un problema e non riuscire a capire tutti i percorsi per la risposta risultante. Se il debugger ti dice di aggiungere un breakpoint alla funzione elencata, allora ci dovrebbe essere qualche informazione da qualche parte per ottenere quell'informazione. Speriamo che questo riduca la frustrazione di alcuni di quelli là fuori che cercano di trovare questa risposta.

+1

Risposta eccezionale. Grazie per aver dedicato del tempo a mettere insieme questo post. – Andrew

+1

idem. Quel punto di rottura è stato di grande aiuto, anche se il mio problema si è rivelato completamente diverso. Grazie per aver dedicato del tempo. –

+1

FYI, non sono sicuro se il nome dell'eccezione è cambiato o perché il mio era in un objc piuttosto che in un file objC++, ma ho dovuto impostare il punto di interruzione per interrompere su __NSAutoreleaseNoPool invece di objc_autoreleaseNoPool. Spero che aiuti qualcuno prima o poi. Il post originale è stato MOLTO utile. – stuckj

1

Molti dei metodi nel cacao api restituiscono oggetti autorelocati. In particolare, quei metodi che restituiscono un oggetto che non inizia con init, ad esempio [NSNumber numberWithLong:]. Se non si dispone di una piscina autorelease, tali oggetti saranno trapelati. È possibile trovare ulteriori informazioni sull'uso di NSAutoreleasePool nello documentation.

+0

Cosa significa? Cosa posso fare per risolvere questo problema – Andrew

+0

Grazie. Lo guarderò nello – Andrew

+0

ne metto uno nel main dove avvii l'app e non devi pensare e usa solo la bellezza che è gli oggetti auto-rilasciati :) – chikuba

1

Significa che è necessario creare un pool di autorelease sul thread che si verifica. Altrimenti, gli oggetti allocati non verranno distrutti (come suggerito dal messaggio). Quindi, interrompi/metta in pausa il simbolo, quindi porta lo stack alla voce del thread (o programma) e aggiungi un pool di autorelease. È tutto.

+0

Si presenta prima dell'app del. Finisce, ma ho commentato riga per riga l'intera faccenda, e sto ancora perdendo oggetti. Qualche pensiero? – Andrew

+0

è necessario aggiungere un pool di autorelease. in esecuzione in precedenza rispetto al punto di esecuzione in cui viene colpito il punto di interruzione. se si trova sul thread principale, quindi aggiungi un pool di autorelease a 'int main()' (nota: il tuo modello di progetto probabilmente lo avrebbe fatto per te). in caso contrario, normalmente lo aggiungere alla voce del thread. – justin

Problemi correlati