避免抛异常

Tip 不要 @throw Objective-C 异常,同时也要时刻准备捕获从第三方或 OS 代码中抛出的异常。 我们的确允许 -fobjc-exceptions 编译开关(主要因为我们要用到 @synchronized ),但我们不使用 @throw。为了合理使用第三方的代码,@try、@catch 和 @finally 是允许的。如果你确实使用了异常,请明确注释你期望什么方法抛出异常。 不要使用 NS_DURING、NS_HANDLER、NS_ENDHANDLER、NS_VALUERETURN 和 NS_VOIDRETURN 宏,除非你写的代码需要在 Mac OS X 10.2 或之前的操作系统中运行。 注意:如果抛出 Objective-C 异常,Objective-C++ 代码中基于栈的对象不会被销毁。比如: 1. class exceptiontest { 2. public: 3. exceptiontest() { NSLog(@"Created"); } 4. ~exceptiontest() { NSLog(@"Destroyed"); } 5. }; 6.   7. void foo() { 8. exceptiontest a; 9. NSException *exception = [NSException exceptionWithName:@"foo" 10. reason:@"bar" 11. userInfo:nil]; 12. @throw exception; 13. } 14.   15. int main(int argc, char *argv[]) { 16. GMAutoreleasePool pool; 17. @try { 18. foo(); 19. } 20. @catch(NSException *ex) { 21. NSLog(@"exception raised"); 22. } 23. return 0; 24. }

会输出: 注意:这里析构函数从未被调用。这主要会影响基于栈的 smartptr,比如 shared_ptr、linked_ptr,以及所有你可能用到的 STL 对象。因此我们不得不痛苦的说,如果必须在 Objective-C++ 中使用异常,就只用 C++ 的异常机制。永远不应该重新抛出 Objective-C 异常,也不应该在 @try、@catch 或 @finally 语句块中使用基于栈的 C++ 对象。