Gestione degli errori Objective-C

Nella programmazione Objective-C, la gestione degli errori è fornita con la classe NSError disponibile in Foundation framework.

Un oggetto NSError incapsula informazioni di errore più ricche ed estensibili di quanto sia possibile utilizzando solo un codice di errore o una stringa di errore. Gli attributi principali di un oggetto NSError sono un dominio di errore (rappresentato da una stringa), un codice di errore specifico del dominio e un dizionario di informazioni utente contenente informazioni specifiche dell'applicazione.

NSError

I programmi Objective-C utilizzano oggetti NSError per trasmettere informazioni sugli errori di runtime di cui gli utenti devono essere informati. Nella maggior parte dei casi, un programma visualizza queste informazioni sull'errore in una finestra di dialogo o in un foglio. Ma può anche interpretare le informazioni e chiedere all'utente di tentare di recuperare dall'errore o tentare di correggere l'errore da solo

L'oggetto NSError è costituito da:

  • Domain - Il dominio di errore può essere uno dei domini NSError predefiniti oppure una stringa arbitraria che descrive un dominio personalizzato e il dominio non deve essere nullo.

  • Code - Il codice di errore per l'errore.

  • User Info - Il dizionario userInfo per l'errore e userInfo potrebbe essere nullo.

L'esempio seguente mostra come creare un errore personalizzato

NSString *domain = @"com.MyCompany.MyApplication.ErrorDomain";
NSString *desc = NSLocalizedString(@"Unable to complete the process", @"");
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : desc };
NSError *error = [NSError errorWithDomain:domain code:-101 userInfo:userInfo];

Ecco il codice completo dell'esempio di errore precedente passato come riferimento a un puntatore:

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
-(NSString *) getEmployeeNameForID:(int) id withError:(NSError **)errorPtr;
@end

@implementation SampleClass

-(NSString *) getEmployeeNameForID:(int) id withError:(NSError **)errorPtr {
   if(id == 1) {
      return @"Employee Test Name";
   } else {
      NSString *domain = @"com.MyCompany.MyApplication.ErrorDomain";
      NSString *desc [email protected]"Unable to complete the process";
      NSDictionary *userInfo = [[NSDictionary alloc] 
      initWithObjectsAndKeys:desc,
      @"NSLocalizedDescriptionKey",NULL];  
      *errorPtr = [NSError errorWithDomain:domain code:-101 
      userInfo:userInfo];
      return @"";
   }
}

@end

int main() {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   SampleClass *sampleClass = [[SampleClass alloc]init];
   NSError *error = nil;
   NSString *name1 = [sampleClass getEmployeeNameForID:1 withError:&error];
  
   if(error) {
      NSLog(@"Error finding Name1: %@",error);
   } else {
      NSLog(@"Name1: %@",name1);
   }
   
   error = nil;
   NSString *name2 = [sampleClass getEmployeeNameForID:2 withError:&error];

   if(error) {
      NSLog(@"Error finding Name2: %@",error);
   } else {
      NSLog(@"Name2: %@",name2);
   }

   [pool drain];
   return 0; 
}

Nell'esempio precedente, restituiamo un nome se l'id è 1, altrimenti impostiamo l'oggetto errore definito dall'utente.

Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:

2013-09-14 18:01:00.809 demo[27632] Name1: Employee Test Name
2013-09-14 18:01:00.809 demo[27632] Error finding Name2: Unable to complete the process