2009-10-01 9 views
10

Sono nuovo nell'obiettivo-c e sto cominciando a chiedermi quale sia il modo comune/standard/corretto per gestire e catturare gli errori?Errori di ritorno nell'obiettivo-

Sembra che sia possibile utilizzare NSError per eseguire questa operazione, è una buona idea o un dirottamento del cacao?

risposta

17

Sono sicuro che questo è ciò che la classe NSError è lì da fare: fornire dettagli sugli errori. Il modello più comune che vedrete è un metodo che prende un puntatore ad un oggetto NSError, come in:

- (id)doSomethingWithArgument:(id)arg error:(NSError **)error

Il metodo restituisce un valore (o, eventualmente, nil) per il risultato di fare qualcosa, ma se il la chiamata fallita posiziona un oggetto NSError sul puntatore passato con dettagli sull'errore. La documentazione è responsabile della specifica di ciò che viene restituito se il metodo incontra un errore.

L'altro metodo che viene in mente è il blocco @throw - @catch; tuttavia, in Objective-C @throw un'eccezione può essere piuttosto dispendiosa dal punto di vista computazionale e in genere è consigliabile farlo solo in situazioni davvero eccezionali.

Modifica: wow, risulta che molte persone hanno opinioni molto forti su @throw eccezioni. Per riassumere il commento (molto utile) sul tema:

  • generare eccezioni dovrebbero trattare il più delle volte con l'errore programmatore (situazioni che dovrebbe mai accadere, e simili); le eccezioni non devono essere utilizzate per la normale gestione degli errori. Utilizzare invece il metodo error illustrato in precedenza o pubblicare istanze di NSNotification.
  • Se si finisce di utilizzare estensivamente i blocchi @throw/@catch, prestare molta attenzione alla logica che li circonda. Objective-C fornisce molti modi per staccare i metodi da eseguire in altri thread, o ritardare l'esecuzione, ecc. Prestare molta attenzione a tenere conto di tutte quelle possibilità quando si scrive il codice.

Infine, un altro punto molto valido:

  • Se si utilizza l'oggetto error passato a un metodo, il valore di ritorno dovrebbe indicarlo. Non tentare di eseguire entrambe le operazioni (restituire un oggetto parzialmente valido e impostare l'oggetto error).
+2

Provare a @throw qualcosa che verrà catturato al di fuori del proprio ambito ha anche molti problemi di logica sottile in ObjC. Che cosa succede se sei chiamato da un NSTimer per esempio? Chi prenderà l'eccezione (ed eviterà di schiantarsi)? Le eccezioni ObjC non sono abbastanza potenti per gestire gli idiomi comuni di ObjC. In genere sono utili solo per gestire errori di programmazione. NSError è sicuramente il modo giusto per andare se hai bisogno di un oggetto ricco di errori per uso generale. –

+2

Per chiarire, le "situazioni veramente eccezionali" in Cocoa sono quasi sempre causa di errore del programmatore, e sono solitamente irrecuperabili, o almeno facilmente evitabili con i controlli appropriati e necessari. Lanciare un'eccezione solo per segnalare qualcosa al programmatore non è una buona pratica in Objective-C, e oggigiorno è persino scoraggiata in Java, non a causa del costo computazionale, ma perché aumenta notevolmente la complessità del codice client. –

+4

Continuando questo concetto, anche l'idea della gestione centralizzata degli errori ha implementazioni migliori rispetto alle eccezioni in Cocoa. Lancio spesso errori in NSNotifications che vengono osservati da alcuni oggetti di gestione degli errori centrali per fornire feedback agli utenti. Se accoppiato con l'incapsulamento della logica retry di NSError, ciò può rendere "post a notification and return" una soluzione molto efficace per gli errori che impattano sull'utente. –