Tratamento de Exceptions em Objective-C

A linguagem Objective-C possui uma sintaxe para tratamento de exceptions parecido com Java e C++. As exceptions podem ser do tipo NSException, NSError ou podem ser classes customizadas que são subclasses de NSException.

O suporte a exception é feito pelas diretivas de compilação: @try, @catch, @throw, e @finally. A seguir irei definir o signigicado de cada diretiva.

@try: inicia um bloco de tratamento de exception, dentro dele deve estar todo código que pode ou deve lançar alguma exception.

@catch: contém o tratamento de uma determinada exception lançada pelo código contido no bloco @try.

@throw: sua finalidade é lançar uma exception.

@finally: todo código contido neste bloco será executado independente de uma exception ser lançada ou não dentro do bloco @try.

A sintaxe comum para declar um bloco @try..@catch..@finally é:

1
2
3
4
5
6
7
8
9
@try {
  //codigo aqui
}
@catch( NSException *exception ) {
  //tratamento da exception aqui  
}
@finally {
  //codigo sempre executado aqui  
}

Agora vou criar um pequeno exemplo para demostrar o bloco funcionando. Irei criar uma instancia da classe NSObject e dentro do bloco @try irei invocar o método doNothing que não existe e com isso será lançada um NSException.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NSLog( @"Creating the instance of NSObject" );
NSObject *object = [[NSObject alloc] init];

@try {
  NSLog( @"try block" );
  [object doNothing];
}
@catch( NSException *exception ) {
  NSLog( @"catch block" );
  NSLog(@"main: Caught %@: %@", [exception name], [exception  reason]);
}
@finally {
  NSLog(@"finally block");
}

O resultado desse exemplo é:

1
2
3
4
5
6
App3[1594:10b] Creating the instance of NSObject
App3[1594:10b] try block
App3[1594:10b] *** -[NSObject doNothing]: unrecognized selector sent to instance 0x105950
App3[1594:10b] catch block
App3[1594:10b] main: Caught NSInvalidArgumentException: *** -[NSObject doNothing]: unrecognized selector sent to instance 0x105950
App3[1594:10b] finally block

Podemos tratar diversas exception em um único bloco @try, utilizando vários blocos @catch um em seguida do outro. Lembrando que você deve tratar primeiro as exceptions mais específicas e depois as mais genéricas. Veja um exemplo abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
@try {
  //codigo aqui
}
@catch( MyCustomException *exception ) {
  //tratamento da exception aqui  
}
@catch( NSException *exception ) {
  //tratamento da exception aqui  
}
@finally {
  //codigo sempre executado aqui  
}

Agora vou demonstrar o uso da diretiva @throw que serve para lançar uma nova exception, seu uso é bem simples bastando apenas informar a instancia da exception que será lançada.

1
2
3
4
5
6
7
8
@try {
  NSLog( @"try block" );
  NSException *exception = [NSException exceptionWithName:@"HotTeaException" reason:@"The tea is too hot"  userInfo:nil];
  @throw exception;
}
@catch( NSException *exception ) {
  NSLog(@"main: Caught %@: %@", [exception name], [exception  reason]);
}

No exemplo anterior repare que não utilizei a diretiva @finally apenas para demonstrar que seu uso não é obrigatorio. O resultado apresentado desse código é:

1
2
App3[1886:10b] try block
App3[1886:10b] main: Caught HotTeaException: The tea is too hot

Com isso já temos um bom conhecimento de como tratar exceptions em nosso código Objective-C.


comments powered by Disqus