2012-03-15 10 views
12

Lo sto facendo religiosamente da un paio di anni. Controllo per la validità del self dopo aver chiamato [super init...] metodi:Perché controlliamo tutti se (autonomamente) nei metodi init?

self = [super init]; 
if (self != nil) { 
    // initialize 
} 
return self; 

Si può fare questo in una varietà di modi, come this question riassume bene, ma questa domanda è sulla sintassi, il mio è il concetto.

Recentemente ho ricevuto una domanda da un collega che sta imparando Objective-C e mi ha chiesto "perché dovrei provare per l'esistenza di me stesso, non è ovvio che sia lì?" e la mia risposta breve era "err, sì, beh, ci sono casi in cui può fallire, ecco perché." Ma la risposta lunga è che davvero non mi capisco perché ci proviamo dappertutto, quando le istanze in cui potrebbe fallire sono molto rare. Apple's reference guide ci parla di alcuni casi specifici, come quando si inizializza con i file o quando si tratta di singleton. Ma suona come eccezioni molto rare alla regola che [super init] dovrebbe funzionare.

Quindi la mia domanda per voi è questa: Perché testiamo sempre la validità di sé? Stiamo semplicemente implementandolo ovunque per catturare quell'unica eccezione dove si verifica? Perché non saltare l'intera cosa if (self) e inizializzare il nostro oggetto se le probabilità di successo sono al 100% (o non è mai così)?

P.S. Mi rendo conto che questa domanda deve essere duplice poiché è così semplice, ma le mie query di ricerca hanno ricevuto molte altre domande sulla sintassi dell'inizializzazione. I collegamenti duplicati sono apprezzati, evviva!

+3

possibile duplicato di [In Objective-C perché dovrei controllare se self = \ [super init \] non è nullo?] (Http://stackoverflow.com/questions/1287950/in-objective-c-why- should-i-check-if-self-super-init-is-not-nil) – JeremyP

risposta

6

Ecco l'argomento a helpful old article sull'argomento, includendo anche alcuni equivoci comuni sull'inizializzatore. Direi che l'idea di base è che una particolare classe non debba preoccuparsi dell'implementazione della sua superclasse, quindi controlliamo sempre per nil in caso di errore.

+1

L'articolo collegato è azzeccato. Sfortunatamente, su questo argomento ci sono molte informazioni errate, tra cui alcuni dei luminari noti come Wil Shipley (anche se Wil ha corretto il suo post su questo argomento in fondo. aggiunge poco, semmai, all'articolo di Mike Ash collegato dal rispondente.) – ipmcc

+0

Questo articolo è davvero utile, risponde a tutte le mie domande e poi ad alcune. Grazie @jtbandes! – epologee

1

uhm ... questa è sicuramente una buona domanda, vorrei averlo fatto. io non sono un esperto in Objective-C, ma vorrei cercare di dare il mio parere, senza paura di downvoter :-)

Posso sentire la tua frustrazione, ma:

err, yeah, well there's instances where it can fail, so that's why. 

E 'una buona perfettamente risposta. Penso che tu non stia controllando da solo, ma stai controllando se l'oggetto super è stato inizializzato correttamente, per me è un altro punto di vista.

Suppongo in ogni caso che sia sempre buona norma controllare se l'oggetto è stato allocato e inizializzato correttamente, soprattutto nell'obiettivo-c che si trova in cima a C con tutti i problemi di allocazione della memoria masquerade. Iniziamo dopo "allocare" e si suppone inizializzare l'oggetto assegnato con variabili ecc ...

Per esempio, in linguaggi come Java dove la catena di costruttori è ben definita e controllata dal compilatore, non riuscendo a costruire un oggetto risulterà in un errore puntatore nullo all'utilizzo successivo di quell'oggetto. Spesso l'allocazione dell'oggetto in Java è priva di errori, ma spesso l'utilizzo di metodi deve essere circondato da un blocco di errore try/catch ad hoc. Quindi il controllo viene effettuato successivamente nel ciclo di vita dell'applicazione.

In ogg-c, invece, si può avere un oggetto nullo per molte ragioni, e se non si verifica un arresto anomalo dell'applicazione, è possibile terminare l'invio di un messaggio a un oggetto non valido. Devo essere sincero, quando eseguo l'istanza direttamente da una sottoclasse di NSObject, non conosco l'utilità di controllare nil. Ma se sto estendendo una classe in un framework, o una libreria statica fornita da altri, mi sentirei sicuramente al sicuro con un controllo per la validità dell'oggetto.

Problemi correlati