2010-03-18 15 views
11

Devo sempre rilasciare se c'è un errore in init, o dovrei farlo solo se ho inizializzato le variabili di istanza prima?Devo sempre rilasciare self per metodi init falliti?

Per dirla in altro modo, questo modello è valido? C'è un momento in cui non dovrei rilasciare me stesso all'interno di un metodo init, o dovrei presumere che se il flusso di controllo entra in init, self ha almeno un conteggio di ritenzione pari a 1?

- (id)init 
{ 
if ((self = [super init]) == nil) 
{ 
    [self release]; 
    return nil; 
} 

//do some init stuff 
if (somethingFailed) 
{ 
    [self release]; 
    return nil; 
} 
return self; 
} 

risposta

17

Se qualche controllo avete bisogno nel vostro metodo di inizializzazione non riesce, allora sì si dovrebbe rilasciare self. Si noti tuttavia che se [super init] restituisce nil, non ha senso inviare il rilascio a self come self è nil. Questo è in realtà di buon occhio da Apple:

Si dovrebbe chiamare solo [self release] al punto di errore. Se si ottiene nil indietro da una chiamata dell'inizializzatore della superclasse, non si dovrebbe chiamare anche release.

Esempio:

- (id)init 
{ 
    self = [super init]; 
    if(self) { 
     // do some init stuff 

     if (somethingFailed) 
     { 
      [self release] 
      self = nil; 
     } 
    } 

    return self; 
} 

vedere anche la documentazione di Mac Dev Center sul Handling Initialization Failure

+0

Ah, sembra così ovvio ora che si punta fuori. Ero un po 'buttato fuori perché sto invocando il rilascio su un oggetto che non ho richiamato alloc/copy/new etc on. – leo

+1

Sì, il principio di base è che chiunque incontri per la prima volta un errore nell'inizializzazione dovrebbe rilasciare lo spazio allocato su cui viene chiamato init, e quindi dovrebbe restituire zero. Dal momento che tutti gli altri diventano nulli, non hanno modo di rilasciare la memoria, quindi perché si dovrebbe chiamare il rilascio su se stessi in modo da evitare una perdita di memoria. –

+0

Ha senso, grazie. – leo

Problemi correlati