2009-08-16 18 views
9

Ci sono molti casi in cui si dovrebbe allocare un'istanza e rilasciarla subito dopo che è stata assegnata a qualcos'altro, che la mantiene internamente.È meglio autorelease o release subito dopo?

Per esempio,

 
UIView *view = [[UIView alloc] initWithFrame...]; 
[self addSubView:view]; 
[view release]; 

Ho sentito la gente che suggerisce che andiamo con autorelease piuttosto che di rilascio subito dopo.

Quindi il comando precedente diventa:

 
UIView *view = [[[UIView alloc] initWithFrame...] autorelease]; 
[self addSubView:view]; 

Qual è la migliore pratica qui? Pro e contro?

risposta

14

Nella maggior parte dei casi, non importa in alcun modo. Poiché -autorelease significa semplicemente che l'oggetto verrà rilasciato alla fine dell'iterazione corrente del ciclo di esecuzione, l'oggetto verrà rilasciato in entrambi i casi.

Il più grande vantaggio dell'utilizzo di -autorelease è che non devi preoccuparti della durata dell'oggetto nel contesto del tuo metodo. Quindi, se in seguito decidi di voler fare qualcosa con un oggetto diverse righe dopo l'ultimo utilizzo, non devi preoccuparti di spostare la tua chiamata su -release.

L'istanza principale quando si utilizza -release farà una differenza notevole rispetto al utilizzando -autorelease è se si sta creando un sacco di oggetti temporanei nel metodo. Ad esempio, si consideri il seguente metodo:

- (void)someMethod { 
    NSUInteger i = 0; 
    while (i < 100000) { 
     id tempObject = [[[SomeClass alloc] init] autorelease]; 

     // Do something with tempObject 

     i++; 
    } 
} 

Con il tempo questo metodo termina, hai 100.000 oggetti seduti in piscina autorelease attesa di essere rilasciato. A seconda della classe di tempObject, questo potrebbe o non potrebbe essere un grosso problema sul desktop, ma sicuramente sarà sull'iPhone con limitazioni di memoria. Pertanto, dovresti utilizzare lo -release su -autorelease se stai allineando molti oggetti temporanei. Ma, per molti/la maggior parte degli usi, non vedrai nessuna grande differenza tra i due.

+3

+1. l'autorelease ha un sacco di critiche sulle prestazioni (la scia che raramente ho visto è supportata da numeri in un normale codice non a ciclo ampio), ma il salvataggio automatico consente anche di risparmiare un sacco di perdite quando il codice viene rifatto. Uso la versione più frequente nelle routine di basso livello poiché non so se potrebbero essere chiamati in un loop di grandi dimensioni ad un livello più alto. Se si intende utilizzare la versione, tuttavia, è necessario impostare immediatamente la variabile su nil se la variabile sarà ancora nell'ambito. Non rilasciare mai un oggetto ma avere ancora un puntatore. –

5

Sono d'accordo con Matt Ball. Vorrei solo aggiungere che, se vi trovate usando spesso questo modello, può essere utile a dare una categoria rapida:

@interface UIView (MyCategories) 
- (UIView *)addNewSubviewOfType:(Class)viewType inFrame:(NSRect)frame; 
@end 

@implementation UIView (MyCategories) 
- (UIView *)addNewSubviewOfType:(Class)viewType inFrame:(NSRect)frame 
{ 
    UIView * newView = [[viewType alloc] initWithFrame:frame]; 
    [self addSubView:newView]; 
    return [newView autorelease]; 
} 
@end 

che può essere usato come segue:

UIView * view = [someView addNewSubviewOfType:[UIView class] 
             inFrame:someFrame]; 

E ancora opere con altri tipi, purché siano derivati ​​da UIView:

UIButton * button = [mainView addNewSubviewOfType:[UIButton class] 
              inFrame:buttonFrame]; 
4

io di solito vado per -release piuttosto che -autorelease quando possibile. Questo deriva da anni di esperienza nel debugging e nel miglioramento del codice Objective-C di altre persone. Il codice che usa autorelease in tutto il mondo rende più difficile eseguire il debug quando un oggetto viene sovrascritto, poiché il rilascio extra avviene lontano dal codice errato.

È anche il caso che molte persone usano autorelease quando non capiscono come funziona la gestione della memoria del cacao. Impara le regole, impara l'API e non avrai quasi mai bisogno di autorelasciare un oggetto.

Un ultimo punto secondario è che se non è necessario il comportamento di autorelease, l'uso della funzione di autorelease aggiunge semplicemente inutilmente del lavoro extra da fare al programma.