6

A mio parere, quando un oggetto viene inviato un messaggio autorelease, se non esistono pool di autorespirazione diversi da quello in main.m, l'oggetto viene inserito in quello in main.m. Supponendo che sia corretto, ho un paio di domande:Pool di autorelease in Objective-C - rilasciare AutoreleasePool principale?

1) Tutti gli oggetti autoreleased rimangono in quella piscina fino alla fine della app?

2) Se 1 è vero, la creazione di un oggetto autoreleased senza un pool di autorelease locale (quindi collocando quell'oggetto nel pool main.m) mantiene quell'oggetto in memoria fino a quando non viene ricevuta la terminazione dell'app o un avviso di memoria?

3) Quando il pool di autorilease main.m viene scaricato, a parte quando l'app riceve un avviso di memoria o l'applicazione viene interrotta?

Ad esempio, in un metodo delegato cellForRowAtIndexPath come questo:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Foobar"]; 
if (cell == nil) { 
    // No cell to reuse => create a new one 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Foobar"] autorelease]; 

    // lots of custom stuff 
} 

return cell; 

quando ci sono le cellule effettivamente immessi? Devono essere autorelocati, perché non puoi rilasciarli prima di restituirli, e non puoi rilasciarli dopo, perché sono fuori portata. Secondo la mia attuale comprensione, le celle vengono posizionate nel pool di autorelease più in alto e rilasciate quando il pool viene scaricato/rilasciato. In questo caso, quello sarebbe l'unico pool di autorelease dell'applicazione; quello in main.

4) Il problema con questo è che anche quando ho finito con quelle celle e il controller di visualizzazione è stato rilasciato, le celle rimangono in memoria, sì? Se questo non è il caso, qualcuno potrebbe fornire una spiegazione di come funziona veramente la gestione della memoria in questa situazione? Grazie!

Nota: ho esaminato la documentazione di Apple, ma si parla principalmente di quando utilizzare i propri pool di autorelease locali, ma non molto su come funzionano effettivamente.

risposta

5

1) Tutti gli oggetti autoreleased rimangono in quella piscina fino alla fine della app?

Gli oggetti autoreleased per definizione appartengono al rispettivo pool di autorelease fino a quando il pool non viene scaricato. Quando si invia -autorelease a un oggetto, tale oggetto viene aggiunto a un elenco di oggetti che verrà rilasciato in seguito. I pool di autorelease sono organizzati in uno stack, con il pool in cima alla pila come pool a cui sono stati aggiunti gli oggetti inviati -autorelease. Il pool creato in main() non è generalmente quello in cima allo stack. Ad esempio, il ciclo di esecuzione creerà un pool di autorelease all'inizio di ogni iterazione.

2) Se 1 è vera, non creando un oggetto autoreleased senza piscina autorelease locale (ponendo pertanto oggetto nel pool main.m) tenere l'oggetto in memoria fino al termine del app o una memoria L'avviso viene ricevuto?

Sarebbe se il pool creato in main() fosse il pool più in alto, ma come descritto sopra, che in genere non sarà il caso.

3) Quando è il pool autorelease main.m drenato diverso quando l'applicazione riceve un avviso di memoria o l'applicazione viene terminata?

Non c'è differenza tra il pool creato in main() e qualsiasi altro pool di autorelease. Sono tutti esauriti quando viene rilasciato il pool o alla fine del blocco se si utilizza la direttiva @autorelease.

+0

Hmm ... mi sono sbagliato. Circa un sacco di cose! Grazie per aver perso un po 'di luce –

+8

"Gli oggetti autoreleased per definizione sono mantenuti dal loro pool di autorelease" Questo non è corretto. I pool di autorelease non conservano nulla. L'autorelease non è altro che un meccanismo di messaggi ritardati. Quando si invia -autorelease a un oggetto, non aumenta il conteggio dei ritiri. Aggiunge l'oggetto a un elenco di oggetti a cui verrà inviato un messaggio di -release quando il pool di autorelease viene rilasciato o inviato un messaggio di -drain. – NSResponder

+3

Un paio di punti aggiuntivi: (1) I pool di autorelease sono per thread e, quindi, un oggetto autoreleased non può mai essere passato tra due thread in modo sicuro. (3) Il pool di livello superiore non è probabilmente mai esaurito perché non ha senso; se un'app viene terminata, invierà le notifiche finali "I'm outta here" e quindi exit() direttamente senza preoccuparsi di drenare il pool. – bbum

7

Dal documentation:

Il kit applicazione crea una piscina autorelease sul thread principale all'inizio di ogni ciclo del ciclo di eventi, e lo vuota, alla fine, liberando così tutti gli oggetti autoreleased generati mentre elaborare un evento. Se si utilizza il kit di applicazione, di solito non è necessario creare i propri pool. Se l'applicazione crea molti oggetti autoreleased temporanei all'interno del ciclo degli eventi, tuttavia, potrebbe essere utile creare pool di autorelease "locali" per ridurre al minimo il picco di memoria.

Quindi, gli oggetti autoreleased nel pool predefinito sopravviveranno solo alla durata dell'evento corrente.