11

Capisco che devi stare attento con autorelease su iOS. Ho un metodo che sta restituendo un oggetto è alloc s che è necessario per il chiamante, quindi in questa situazione - a quanto ho capito - ho bisogno di inviare autorelease all'oggetto nel chiamato prima che ritorni.Quando autorelease provoca effettivamente un rilascio in Cocoa Touch?

Questo va bene, ma una volta che il controllo ritorna al telefono (cioè dopo che il mio clic sul pulsante è stato elaborato) sembra che il pool di autorelease sia stato rilasciato. Sospetto che sia così che dovrebbe essere, ma mi chiedo quale sia la migliore pratica per questa situazione.

Ho fatto ricorso all'invio di un messaggio retain dal chiamante in modo che l'oggetto non venga rilasciato e rilasciandolo esplicitamente in dealloc.

È questo l'approccio migliore?

risposta

21

Il pool di autorelease viene in genere rilasciato dopo ogni iterazione del ciclo di esecuzione. Approssimativamente, ogni applicazione Cocoa e Cocoa Touch è strutturato in questo modo:

Get the next message out of the queue 
Create an autorelease pool 
Dispatch the message (this is where your application does its work) 
Drain the autorelease pool 

Ciò che si descrive è il comportamento previsto. Se vuoi mantenere un oggetto in giro più a lungo, dovrai mantenerlo esplicitamente.

2

Sì, questo è l'approccio migliore. L'autorelease è realmente inteso solo per le interazioni nel codice che conosci. Una volta archiviato un oggetto, dovresti sapere che l'oggetto che contiene un riferimento non morrà/uscirà dall'ambito finché non avrai finito con l'oggetto, o dovrai conservare l'oggetto.

1

È garantito che gli oggetti autorelocati verranno rilasciati dopo la fine del metodo. Dopo tutto, il metodo che ha chiamato il tuo metodo potrebbe aver creato il proprio pool e rilasciarlo subito dopo il tuo metodo.

+0

A rigor di termini, anche questo non è garantito, dal momento che si potrebbe creare una piscina in un metodo, autorelease alcuni oggetti, e svuotare la piscina in un altro metodo. Un design dubbio, ma valido: gli oggetti dureranno dalla creazione del pool al drenaggio della piscina, indipendentemente dal metodo che ha creato il ritorno del pool. –

13

L'utilizzo di autorelease è un modo di dire: "Oggetto, non ti voglio più, ma ti passerò da qualcun altro che potrebbe volerti, quindi non sparire ancora". Quindi l'oggetto rimarrà abbastanza a lungo da poterlo restituire da un metodo o darlo a un altro oggetto. Quando un codice desidera mantenere l'oggetto, deve rivendicarne la proprietà tramite retain.

Vedere the memory management guidelines per tutto ciò che è necessario sapere per utilizzare autorelease correttamente.

+0

Buona risposta, ma questo è sicuro? C'è un esempio di tempo in cui restituisci un oggetto che tu [[[allocazione oggetto] init] autorelease] ', ma poi l'oggetto scompare prima che tu avessi la possibilità di usarlo? – bobobobo

+0

@bobobobo: non se stai seguendo le regole di gestione della memoria. Il comportamento di 'autorelease' è abbastanza prevedibile - l'oggetto rimarrà in attesa finché il pool di autorelease corrente non sarà esaurito, cosa che non accadrà fino alla fine del ciclo di eventi corrente (a meno che non lo facciate intenzionalmente prima).Se, per esempio, puntate una variabile di istanza sull'oggetto ma non la mantenete e poi provate ad accedervi molto dopo, l'oggetto sarà scomparso prima che aveste la possibilità di usarlo - ma è perché avete rotto la gestione della memoria contratto quando non hai mantenuto l'oggetto. – Chuck

3

Ecco un examle fornite in the Apple Memory Management document:

– (id)findMatchingObject:(id)anObject 
{ 
    id match = nil; 
    while (match == nil) { 
     NSAutoreleasePool *subPool = [[NSAutoreleasePool alloc] init]; 
     /* Do a search that creates a lot of temporary objects. */ 
     match = [self expensiveSearchForObject:anObject]; 
     if (match != nil) { 
      [match retain]; /* Keep match around. */ 
     } 
     [subPool release]; 
    } 
    return [match autorelease]; /* Let match go and return it. */ 
} 
Problemi correlati