考虑以下Cocoa/Obj-C代码片段:
MyClass *obj; @try { [obj doSomething]; } @catch (NSException * e) { NSLog(@"Exception occurred: %@", [e description]); } @finally { [obj cleanUp]; }
和
MyClass *obj; @try { [obj doSomething]; } @catch (NSException * e) { NSLog(@"Exception occurred: %@", [e description]); } [obj cleanUp];
在什么情况下会在第一个片段导致[obj cleanUp]
被调用,而第二个将无法在导致[obj cleanUp]
被称为?换句话说,在@finally
使用Cocoa异常处理时,在什么情况下是非冗余的?
在这些情况下没有区别,因为吞下了异常.这里有两种情况,其中有是一个区别:
调用[obj cleanUp]:
MyClass *obj; @try { [obj doSomething]; } @catch (NSException * e) { @throw; } @finally { [obj cleanUp]; // called when exception is caught }
[obj cleanUp]未被调用:
MyClass *obj; @try { [obj doSomething]; } @catch (NSException * e) { @throw; } [obj cleanUp]; // not called when exception is caught
值得注意的是,@finally
当控件以任何理由退出@try
块时,块中的代码将运行,即使是通过或.例如:return
goto
@try { doStuff(); if(bail){ return; } doMoreStuff(); } @finally { [obj cleanUp]; } [obj announceSuccess];
[obj cleanUp]
即使bail
是真的也会执行,但[obj announceSuccess]
不会.
在那种情况下,你要压缩异常,没有.@finally
用于在您不捕获异常或重新抛出异常时进行清理,在任何一种情况下都会对调用代码留下最终异常响应.由于Cocoa中的异常仅被用于编程错误并因此很少发生,因此这是完全合理的事情.
这也是值得指出的一个情况下,你并不需要使用@finally
,这是当你建立自己的自动释放池.当"父"自动释放池被销毁时,任何尚未清理的内部池也将被破坏.如果您确实尝试自行清理它,则需要从自动释放池中提升异常.