2010-01-29 11 views
12

Nell'esempio di codice seguente dalla Guida alla programmazione dei dati principali, NSFetchRequest viene creato con con autorelease mentre NSSortDescriptor non viene creato con autorelease. Perché NSSortDescriptor non è stato creato con autorelease? È una questione di preferenza?Autorelease o Not to Autorelease

NSManagedObjectContext *moc = [self managedObjectContext];  
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" 
                inManagedObjectContext:moc]; 

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
[request setEntity:entityDescription]; 
// Set example predicate and sort orderings... 
NSNumber *minimumSalary = ...; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(lastName LIKE[c]'Worsley') AND (salary > %@)", minimumSalary];  
[request setPredicate:predicate]; 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" 
                   ascending:YES]; 
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
[sortDescriptor release]; 
NSError *error; 
NSArray *array = [moc executeFetchRequest:request error:&error]; 
if (array == nil){ 
    // Deal with error... 
} 

risposta

35

Quando si esegue l'autorilease, si sta sostanzialmente dicendo: "Non ho più bisogno di questo, ma chiunque è libero di prenderlo (prima che il pool di rilascio automatico venga scaricato)". Quando rilasci esplicitamente un oggetto stai dicendo: "Non ne ho più bisogno e, a meno che qualcun altro non abbia già detto diversamente (acquisito), dovrebbe essere immediatamente deallocato".

Di conseguenza, l'autorelease non è normalmente la cosa sbagliata. È richiesto quando si desidera passare nuovamente gli oggetti al mittente di un messaggio senza richiedere al mittente di occuparsi del rilascio dell'oggetto.

+1

Questa è la spiegazione più succinta che ho letto per autorelease. – TechZen

+0

Ottima risposta davvero! +! La modifica automatica –

26

Per AutoRelease o non autorelease

Questo è la questione.

Se è più nobile per il programmatore di subire le fionde e le frecce di perdite di memoria o di prendere le armi contro un mare di puntatori differiti e conservandoli, terminarli ... È un compimento devotamente da desiderare! Sì, c'è il problema! ... Perché in quegli oggetti sovrascritti, quali arresti potrebbero verificarsi quando facciamo riferimento ad oggetti che non ci sono, devono darci una pausa.

Non ho potuto aiutare me stesso. Prenderò il colpo rep. Non mi pento di nulla!

+0

+0: hai già ottenuto quattro punti da questo :) –

+0

+1: assolutamente geniale. –

+0

Divertente, ma si intromette nella ricerca della vera risposta. – finnw

0

La domanda è questa: in che modo l'utilizzo di autorelease o release influisce sulla durata di un oggetto?

In entrambi i vostri esempi non fa differenza.

Entrambi NSFetchRequest e NSSortDescriptors saranno vivi fino alla fine del metodo, indipendentemente dal fatto che siano rilasciati o autorelati.

Se si crea un'istanza di un oggetto e quindi lo si consegna a un altro oggetto (ad esempio, un NSArray), esso rimane attivo indipendentemente dal fatto che si chiami rilascio o autorelease.

-1

Entrambi mantengono e autorelease, funzionalmente conservano un oggetto ma non fondono. Le differenze sono che i conteggi di mantenimento possono essere decrementati solo da un altro oggetto mentre i conteggi autoreleased vengono decrementati automaticamente quando NSAutoreleasePool viene scaricato. Se nessun altro oggetto ha trattenuto l'oggetto autorelasciato al momento del drenaggio della piscina, si spegne.

Fondamentalmente, si utilizza la funzione di autorelease quando si desidera assicurarsi che un oggetto si blocchi nel metodo corrente e possa essere passato ad altri oggetti ma non si desidera che si debba tenere traccia della sua versione.

Nel codice di esempio, l'autorelease è solo una misura di sicurezza. L'oggetto NSPredicate viene rilasciato perché il suo lavoro è finito ma il programmatore voleva assicurarsi che l'oggetto NSFetchRequest rimanesse in sospeso. Non è necessario utilizzare "autorelease" in questo caso, ma se hai perso il conto delle tue versioni, il file fetchRequest potrebbe scomparire.D'altra parte, non lo si vuole orfano e perde, quindi si utilizza la correzione automatica per pulire quando il pool è in fogna.

L'uso più comune di autorelease è quando si crea un numero variabile di oggetti ogni volta. Non vuoi doverli rintracciare tutti così li autorizzi automaticamente e lasciare che la piscina si prenda cura di loro. (Ancora meglio, si crea un pool locale e lo si esaurisce non appena fatto).

Nello standard API Apple, qualsiasi metodo che crea un nuovo oggetto senza le parole chiave 'init', 'new' o 'create 'restituisce un oggetto autoreleased.

-[NSString initWithString:] non è autorelease ma - [NSString stringWithString:] è. Ciò causa problemi negli ambienti di raccolta non Garbage perché stringWithString: restituisce una stringa che sembra comportarsi come un oggetto mantenuto, ma in seguito scomparirà improvvisamente apparentemente a caso quando il pool di autorilease è stato creato negli scarichi.


Edit01: Dal

una piscina autorelease di Apple Docs è un esempio di NSAutoreleasePool che “contiene” altri oggetti che hanno ricevuto un messaggio di autorelease; quando il pool di autorelease viene deallocato, lo invia un messaggio di rilascio a ciascuno degli oggetti . Un oggetto può essere messo in un pool di autorelease più volte e riceve un messaggio di rilascio per ogni volta che è stato inserito nel pool . Pertanto, l'invio autorelease invece di disperdere un oggetto prolunga la durata di tale oggetto in almeno fino alla piscina stessa è rilasciato (l'oggetto può sopravvivere maggiore se viene trattenuto nel intermedio).

Il mantenimento conta e autorelease entrambi mantengono un oggetto vivo dallo stesso meccanismo di conteggio base (ma separato). La principale differenza è che l'oggetto proprietario invia la versione. Con i conteggi mantenuti, è un altro oggetto ma per un conteggio autorecondato è il pool di autorelease.

+0

NON mantiene un oggetto. –

+0

Ho chiarito, è meglio? – TechZen

1

L'oggetto richiesta verrà restituito al chiamante, mentre l'ordinatoreDiDevice viene utilizzato e quindi scartato.

La motivazione per l'autorelease è semplice. Senza di esso, qualsiasi oggetto restituito da una funzione dovrebbe essere rilasciato dal chiamante se non ne ha bisogno. Usare autorelease significa che le funzioni possono restituire un oggetto che, se al chiamante non interessa, o se lo guardano ma non ne tengono un riferimento, possono semplicemente usarlo senza aggiungere altro codice per liberarlo. Solo se stanno mantenendo un riferimento, hanno bisogno di trattenerlo.

Vale la pena pensare esattamente a che cosa significa autorelease. Quando si chiama autorelease su un oggetto, si aggiunge l'oggetto a un elenco e al termine del ciclo dell'applicazione verrà chiamato il rilascio. Questo rende la autorelease esattamente equivalente a una release ritardata.

Il documento Apple sulla gestione della memoria è eccellente e merita un'attenta lettura. http://developer.apple.com/iPhone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

Problemi correlati