2013-09-05 10 views
5

Nella maggior parte degli esempi di Objective-C che ho letto, nonché nella documentazione di Objective-C, gli oggetti vengono sempre controllati per il completamento con esito positivo prima dell'uso.È necessario verificare che gli oggetti siano effettivamente allocati?

Ad esempio:

MyObject *myObject = [[MyObject alloc] init]; 
if (myObject){ 
    //do stuff with the object 
} 
//stuff beyond here is probably not going to work if myObject is nil 

non sarà questa rendere difficile rintracciare bug? Non sono sicuro del motivo per cui l'allocazione fallirebbe a parte la memoria insufficiente, ma non ho mai visto un controllo come questo fatto in Java (il linguaggio da cui sto migrando) subito dopo l'inizializzazione di un oggetto.

Suppongo che renderebbe un'app molto complicata se si controllasse ogni singola allocazione e si provasse a reagire alle allocazioni fallite. Immagino che potresti mostrare un messaggio di errore all'utente in molti casi, ma il numero di rami nel programma probabilmente raddoppierà.

Ma negli esempi che ho visto, non fanno nulla quando l'allocazione fallisce, oltre a saltare qualche codice che sarebbe necessario per l'utente per vedere cosa si aspettano sullo schermo. Sembra che se le allocazioni fallite avvengono davvero molto in pratica, e stai seguendo questo stile di codifica, il risultato sarebbero schermi vuoti, documenti non salvati che l'utente pensa siano stati salvati, dati corrotti che l'utente e il programmatore non sono a conoscenza, ecc.

MODIFICA: Ecco un esempio del tutorial di Apple "La tua terza app iOS: iCloud".

- (NSMetadataQuery*)textDocumentQuery { 
    NSMetadataQuery* aQuery = [[NSMetadataQuery alloc] init]; 
    if (aQuery) { 
     // Search the Documents subdirectory only. 
     [aQuery setSearchScopes:[NSArray 
        arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]]; 

     // Add a predicate for finding the documents. 
     NSString* filePattern = [NSString stringWithFormat:@"*.%@", 
        STEDocFilenameExtension]; 
     [aQuery setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@", 
        NSMetadataItemFSNameKey, filePattern]]; 
    } 

    return aQuery; 
} 
+6

Non ho mai visto il codice farlo in un caso così semplice. Puoi offrire un esempio reale che hai visto? – Chuck

+0

almeno in ios, se il tuo 'alloc' restituisce' nil' per motivi di memoria, la tua app verrà comunque uccisa da os. –

+0

@Chuck Ho aggiunto un esempio. – Tenfour04

risposta

5

Initializers dovrebbe restituire nil se inizializzazione fallisce, questo potrebbe ad esempio verificarsi se initWithFile: è dato un percorso inesistente.

in Objective-C è possibile inviare messaggi a nil (a differenza ad esempio C++, dove non si può chiamare un metodo su NULL), quindi controllando if (object) non è necessario prima di operare su tale oggetto. D'altra parte, se si desidera aggiungere l'oggetto in un array si dovrebbe verificare che non è pari a zero:

SomeClass *anObject = [SomeClass alloc] initializerThatMightReturnNil] 
[anArray addObject:anObject] 

Questo sarebbe un'eccezione, se anObject è nil

Quindi, per rispondere alla tua domanda : In genere non è necessario controllare per nil dopo ogni inizializzazione, ma assicurati di aver capito cosa succede se l'oggetto è nullo.

+0

Grazie per la spiegazione. Ho appena aggiunto un esempio da uno dei tutorial di Apple. Assegnano e inizializzano un NSMetadataQuery con un inizializzatore che non accetta argomenti. E anche se lo facesse, penserei che non vorrai nascondere il tuo errore testando per nil ... vorresti lanciare un'eccezione così sarai in grado di tracciare facilmente il bug durante il test. Ma in questo caso, non so perché il riferimento sarebbe stato nullo immediatamente dopo l'inizializzazione senza argomenti. – Tenfour04

+1

@ Tenfour04 - C'è un sacco di cose strane negli esempi di Apple. Ci sono casi specifici in cui è richiesto il controllo di nil, ma nel caso generale se viene restituito nil è perché l'ambiente dell'app è seriamente compromesso e quindi lasciare che le cose si blocchino "naturalmente" è perfettamente soddisfacente. –

+0

(Giusto per assicurarsi che il commento sopra non sia fuori dal contesto, stiamo parlando di alloc/init calls qui, non del caso generale di una chiamata al metodo che restituisce un puntatore a un oggetto.) –

Problemi correlati