2012-02-12 8 views
5

in Cocoa e Objective C il metodo preferito per la gestione di errore sembra essere utilizzando un oggetto NSError *, per costruire un oggetto errore però, abbiamo bisogno di chiamare il seguente metodoelenco dei codici di errore Gestione per NSError in c obiettivo

+ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict 

La mia domanda è: quali sono alcune delle migliori pratiche per la gestione del dominio degli errori, delle definizioni dei codici di errore e del dizionario delle informazioni utente sull'intera applicazione in modo che il codice di errore, il dominio e le informazioni utente siano sempre coerenti?

risposta

10

Se si dispone di una notevole quantità di errori nella costruzione, la tua vita potrebbe essere molto più semplice utilizzando una classe. Io in realtà uso C++ per questo quindi le chiamate di un programma non ha bisogno può essere rimosso (a differenza objc), ma è possibile utilizzare C, objC, o C++ per questo:

MONErrorDomain.h

// you won't normally need an instance here 
@interface MONErrorDomain : NSObject 

+ (NSString *)domain; // << required override 
- (NSString *)domain; // << returns [[self class] domain] 

// example convenience methods: 
// uses [self domain] 
+ (NSError *)errorWithErrorCode:(NSInteger)errorCode; // << user info would be nil 
+ (NSError *)errorWithErrorCode:(NSInteger)errorCode userInfo:(NSDictionary *)userInfo; 

@end 

MONKoalaError.h

@interface MONKoalaError : MONErrorDomain 

+ (NSError *)outOfEucalyptus; 

@end 

extern NSString * const MONKoalaErrorDomain; 

typedef enum MONKoalaErrorCode { 
    MONKoalaErrorCode_Undefined = 0, 
    MONKoalaErrorCode_OutOfEucalyptus 
} MONKoalaErrorCode; 

MONKoalaError.m

// apple recommends we use reverse domains 
NSString * const MONKoalaErrorDomain = @"com.mon.koala-library.MONKoalaErrorDomain"; 

@implementation MONKoalaError 

+ (NSString *)domain 
{ 
    return MONKoalaErrorDomain; 
} 

+ (NSError *)outOfEucalyptus 
{ 
    NSDictionary * info = …; 
    return [self errorWithErrorCode:MONKoalaErrorCode_OutOfEucalyptus userInfo:info]; 
} 

@end 

Poi la creazione di errore è tutto in un unico luogo per ogni dominio, ed i clienti possono facilmente raccogliere i loro errori senza peraltro riuscire a costruire manualmente:

if (outError) { 
    *outError = [MONKoalaError outOfEucalyptus]; 
} 

e la gestione degli errori assume la forma:

if ([e.domain isEqualToString:MONKoalaErrorDomain]) { 
    switch (e.code) { 
    case MONKoalaErrorCode_OutOfEucalyptus : { 
     self.needsEucalyptus = true; 
… 
+1

Solo un piccolo commento: mentre un codice di errore NSError non dovrebbe essere confuso dal codice di uscita del programma, trovo contro intuitivo avere un codice di errore uguale a 0. Preferisco avere -1 per un errore indefinito. – Alerty

+0

@Alerty '0' viene utilizzato per undefined perché è un valore più prevedibile quando un programmatore introduce un errore logico (ad esempio, messaggi' nil' o utilizza la memoria inizializzata predefinita in debug). vale a dire, l'errore non dovrebbe mai restituire "MONKoalaErrorCode_Undefined" se si tratta di un errore di "MONKoalaErrorCode". – justin

3

Un modo comune è definire alcune costanti appropriate in un file di intestazione e quindi includere tale file di intestazione ovunque sia necessario. Si tratta di un approccio molto semplice, e si presenta come:

const NSString * kMyAppErrorDomain = @"com.example.myapp"; 
const NSInteger kMyAppSomeError = 2; 

// key into user info dictionary 
const NSString * kMyAppProblemKey = @"MyAppProblemKey"; 

Ho visto anche alcune applicazioni che creano metodi di convenienza per la creazione di questi, sia come una categoria a NSError o come una classe di utilità separato o insieme di funzioni. È anche del tutto ragionevole sottoclasse NSError, ad esempio per personalizzare la descrizione localizzata.

Se non lo hai già visto, Apple ha rilasciato lo Error Handling Programming Guide che spiega come dovrebbero essere utilizzati in Cocoa.

+0

ah, la guida alla gestione degli errori è davvero utile. Grazie! – Tony

Problemi correlati