2012-03-13 11 views
5

Ho appreso che l'Objective C ha un modo equivalente di gestire eccezioni come C# in .NET. Inoltre, come dice la documentazione Apple, mi piacerebbe gestire/elaborare le eccezioni, creando un oggetto NSError. Dando uno sguardo da vicino la sezione "Catching diversi tipi di eccezione" nella documentazione exception handlingQual è l'approccio corretto alla gestione delle eccezioni in iOS?

.... Vorrei catturare diversi tipi di eccezione. In. NET Sono abituato a consultare il doc di un metodo di classe per ottenere le possibili eccezioni che può generare. Dove ottenere queste informazioni dai apple-docs? Come faccio a sapere, che tipo di eccezioni un metodo/oggetto/processo può sollevare?

grazie per i vostri suggerimenti

Tom

risposta

5

Come afferma la documentazione di Apple, la maggior parte delle eccezioni viene lanciata in circostanze eccezionali. (Alcune eccezioni non lo sono, come l'accesso a un oggetto dai limiti NSArray.)

.NET incoraggia la gestione delle eccezioni locali. Il cacao è stato scritto per incoraggiare la gestione delle eccezioni di ampio raggio. Il motivo per cui la gestione delle eccezioni locali è in .NET è che ci si aspetta che una parte fallisca in modo atteso (come un errore di rete durante il download di qualcosa). In Cocoa, questo viene gestito utilizzando metodi che restituiscono invece NSErrors. È la stessa cosa, solo più visibile nella firma del metodo.

Una buona regola empirica è che Cocoa emette solo un'eccezione in situazioni in cui non è chiaro come si possa recuperare. (Non confondere questo per le eccezioni che sono gettati in tutto il luogo come in .NET e essendo questo difficile da gestire.)

+0

grazie per il vostro contributo! – Tom

2

sguardo al developer reference for exception handling. Nel cacao non riceviamo eccezioni come nilArgumentException, otteniamo solo NSException. Per dare bel messaggio grana o la manipolazione è possibile effettuare le seguenti operazioni,

if ([[exception name] isEqualToString:MyAppException]) 

Di seguito l'elenco dei nomi di eccezione definiti nel file di intestazione NSException.

FOUNDATION_EXPORT NSString * const NSGenericException; 
FOUNDATION_EXPORT NSString * const NSRangeException; 
FOUNDATION_EXPORT NSString * const NSInvalidArgumentException; 
FOUNDATION_EXPORT NSString * const NSInternalInconsistencyException; 

FOUNDATION_EXPORT NSString * const NSMallocException; 

FOUNDATION_EXPORT NSString * const NSObjectInaccessibleException; 
FOUNDATION_EXPORT NSString * const NSObjectNotAvailableException; 
FOUNDATION_EXPORT NSString * const NSDestinationInvalidException; 

FOUNDATION_EXPORT NSString * const NSPortTimeoutException; 
FOUNDATION_EXPORT NSString * const NSInvalidSendPortException; 
FOUNDATION_EXPORT NSString * const NSInvalidReceivePortException; 
FOUNDATION_EXPORT NSString * const NSPortSendException; 
FOUNDATION_EXPORT NSString * const NSPortReceiveException; 

FOUNDATION_EXPORT NSString * const NSOldStyleException; 

CORREZIONE:

È possibile creare una sottoclasse di classe NSException, come suggerito in uno dei commenti qui sotto, per la cattura di eccezione personalizzata.

+1

Non c'è niente che ti impedisca di sottoclassi NSException e di catturare tipi specifici nel blocco '@ catch' per il tuo codice. –

+0

grazie per la tua risposta – Tom

+0

@GrahamLee. Hai ragione. Si può sicuramente estendere. Anche iniziato a seguire il tuo blog :) – Vignesh

5

movimentazione nel mondo Objective-C errore è probabilmente molto diverso da quello a cui siete abituati . Per dirla in breve, dimentica le eccezioni. La maggior parte degli errori sono gestite da valori di ritorno o passando un puntatore a NSError*:

NSErrror *error = nil; 
BOOL success = [somebody doSomethingWithError:&error]; 
if (!success) { 
    NSLog(@"Got error: %@", error); 
} 

E sul lato callee:

- (BOOL) doSomethingWithError: (NSError**) error 
{ 
    error = error ? error : &(NSError*){ nil }; 
    if (somethingWentWrong) { 
     *error = [NSError …]; 
     return NO; 
    } 
    // All is fine 
    return YES; 
} 

Questo sembra ingombrante, ma in pratica funziona per lo più bene. Nella rara occasione in cui qualcosa può davvero lanciare un'eccezione (come [NSFileHandle writeData:]), la documentazione menziona il fatto, ma non penso che ci si aspetti che analizzi l'eccezione tanto quanto di consueto in altre lingue.

+0

Ciao zoul, grazie per la tua risposta. solo per la mia riassicurazione-> questo significa che una buona pratica sarebbe quella di costruire un blocco try & catch proforma-saggio intorno a tutto il codice nel mio progetto (nel caso in cui ho dimenticato di gestire qualcosa correttamente, come il controllo di un valore nullo) per prevenire il software da arresto anomalo. e in caso contrario sto procedendo bene nello sviluppo e non mi preoccupo più di gestire le eccezioni? -o solo costruire un try-catch-block attorno al mio metodo principale, perché un'eccezione non gestita finirà comunque lì (e quindi loggarlo o presentare un messaggio all'utente) – Tom

+0

Gli oggetti "Null" sono gestiti in modo diverso nell'Obiettivo- C, è legale inviare un messaggio a un oggetto 'nil'. Questo a volte è un bel risparmio di tempo e qualche volta un bell'errore in attesa di succedere. Puoi principalmente dimenticare i blocchi try/catch in Objective-C. Ogni volta che chiami qualcosa che potrebbe fallire, dai un'occhiata a come verrà restituito l'errore. Nella maggior parte dei casi avrai un 'NSError' indietro, quindi è ovvio dalla firma del metodo. Nel piccolo numero di casi rimanenti, la documentazione ti dirà che il metodo potrebbe generare, quindi avrai bisogno di un blocco try/catch lì. Ancora una volta, tali situazioni sono rare. – zoul

+0

grazie per l'input, evviva !!! – Tom