2010-11-30 4 views
5

Non ho notato l'output della mia console per un po 'e ho notato improvvisamente molti errori strani.__NSAutoreleaseNoPool(): Object 0x753c2f0 di classe generale autoreleased senza pool in posizione - appena fuoriuscita

__NSAutoreleaseNoPool(): Object 0x753c2f0 of class General autoreleased with no pool in place - just leaking

__NSAutoreleaseNoPool(): Object 0x753c300 of class __NSArrayM autoreleased with no pool in place - just leaking

non ho idea di dove questo accada?

Edit ..

usa questo

[self performSelectorInBackground:@selector(startupStuff) withObject:sender]; 

Con statupStuff ho questo

General *rdb = [[General alloc] autorelease]; 
[rdb refreshDBData]; 

gli errori avvengono poco dopo codice nel metodo refreshDBData.

+0

stai utilizzando più thread nella tua app? se è così allora succede se non hai inserito NSAutoReleasePool nel metodo thread. – Sanniv

+1

Hai già la tua risposta, quindi solo un commento qui, ma invocare '-autorelease' subito dopo aver richiamato' + alloc' sembra un errore e una brutta abitudine. Perché non chiami '-init'? – d11wtq

risposta

16

I pool di autorelease sono legati ai thread. Se si crea una discussione attraverso performSelectorInBackground, è necessario creare e distruggere un pool di autorelease autonomamente. Quindi è necessario startupStuff a guardare come questo:

- (void)startupStuff:(id)sender 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    // ... everything else you were doing ... 

    [pool drain]; //see comment below 
} 

Aggiunta: Richard sotto fa il punto che di scarico è preferibile liberare riconoscere che (sul desktop, non ancora su iOS) si può eseguire con un garbage collector . parole specifiche di Apple sono (source):

In un ambiente di garbage collection, l'invio di un messaggio di scarico a un pool innesca garbage collection, se necessario; il rilascio, tuttavia, è un no-op. In un ambiente conteggiato di riferimento, lo scarico ha lo stesso effetto del rilascio. In genere, pertanto, è necessario utilizzare lo scarico anziché il rilascio.

Quindi ho corretto il mio esempio. Inutile dire che questa domanda specifica riguarda l'iPhone e attualmente non esiste una garbage collection su quel dispositivo. Quindi il poster di partenza è nello "scarico ha lo stesso effetto del campo di rilascio", non lo "scarico ... attiva la raccolta dei rifiuti, se necessario, il rilascio è comunque un campo non operativo".

+1

drain è preferibile essere rilasciato per gli oggetti NSAutoreleasePool perché funziona sia in ambienti GC che in contatori di riferimento. – Richard

+0

@Richard: grazie per avermelo fatto sapere! Sono stato nel mondo iOS per troppo tempo, ovviamente. Ho corretto la risposta. – Tommy

+0

Grazie per me ha funzionato anche per me. –

0

Prova questa

[self performSelectorInBackground:@selector(startupStuff) withObject:sender]; 

-(void)startupStuff:(id)sender 
{ 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    General *rdb = [[General alloc] init]; 

    [rdb refreshDBData]; 

    [rdb release]; 

    [pool release]; 

} 

Se non il suo lavoro troppo, allora avete bisogno di controllare il metodo refreshDBData .. si sta facendo qualcosa di sbagliato c'è

4

questo:

General *rdb = [[General alloc] autorelease]; 

è sbagliato. Ci dovrebbe sempre essere una chiamata a un inizializzatore; a -init, almeno.

Problemi correlati