首先在Xcode的build选项中,需将 Enable Objective-C Exceptions 选项选为 Yes.
Exception关键字
- @try, @catch, @finally, @throw
1 2 3 4 5 6 7 8 9 10 11 12 13
| @try { } @catch(NSException* exception) { } @finally { }
|
##捕捉不同的异常
1 2 3 4 5 6 7 8 9 10
| @try {} @catch(MyCustomException* custom) {} @catch(NSException* exception) {} @catch(id value) {} @finally {}
|
抛出异常
抛出一个NSException实例的方式有2种:
- 使用@throw
给一个NSException对象发送raise消息
例如:
1 2 3 4 5 6
| NSExcetpion * theException = [NSException exceptionWithName:...]; @throw theException; 或 [theException raise];
|
注意:@try抛出异常不耗资源,然而捕获异常需要耗费资源和速度,因此不能用异常机制作为流程控制和错误处理。
异常和自动释放池(Autorelease Pool)
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| - (void) myMethod { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSDictionary* myDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"asdfasds", nil]; @try { [self processDictionary:myDictionary]; } @catch (NSException *exception) { @throw; } @finally { [pool release]; } }
|
此时在@catch中抛出的异常,将会在@finally执行完之后再处理,因此由于资源池已被释放了,造成该异常 对象被释放,再次抛出时出错。
改进方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| - (void) myMethod { id savedException = nil; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSDictionary* myDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"asdfasds", nil]; @try { [self processDictionary:myDictionary]; } @catch (NSException *exception) { savedException = [e retain]; @throw; } @finally { [pool release]; [savedException autorelease]; } }
|
这里通过先将异常retain,并且这个异常被设为autoreleasse,这样在执行@finally之后,该异常可以仍可被正确的rethrow,并在适当的时候自动释放。