考虑以下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]
?换句话说,在使用Cocoa异常处理时,@finally
在什么情况下是非冗余的?
答案 0 :(得分:15)
在这些情况下没有区别,因为吞下了异常。以下是 差异的两种情况:
[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
答案 1 :(得分:7)
值得注意的是,@finally
块中的代码将在控件退出@try
块因任何原因时运行,即使是通过return
或{{1 }}。例如:
goto
即使@try {
doStuff();
if(bail){
return;
}
doMoreStuff();
}
@finally {
[obj cleanUp];
}
[obj announceSuccess];
为真, [obj cleanUp]
也会执行,但bail
则不会。
答案 2 :(得分:5)
在这种情况下,你要压缩异常,没有。 @finally
用于在您不捕获异常或重新抛出异常时进行清理,在任何一种情况下都会对调用代码留下最终异常响应。由于Cocoa中的异常仅被用于编程错误,因此很少发生,这是完全合理的事情。
还值得指出一个案例,你不需要使用@finally
,这是你设置自己的自动释放池时的情况。当“父”自动释放池被销毁时,任何尚未清理的内部池也将被破坏。如果您确实尝试自行清理它,则需要从自动释放池中提升异常本身。
答案 3 :(得分:1)
当:
答案 4 :(得分:0)
一个较低级别的问题,你为什么要这样做?
try / catch / finally方法在Java中被广泛使用,但几乎没有在Objective-C中使用,并且不是首选方法 - 您根本不需要它,因为库不会像Java库调用那样抛出异常,如果您正在编写自己的库,那么您不应期望调用者会自然地想要查找要捕获的异常。
最广泛使用和理解的约定是具有错误方法回调的委托,或者可能需要通过多级代码传递的更常见故障的通知。如果有一个简单的通知系统,那么这种方法可能会在Java世界中得到更广泛的应用。
委托方法具有与在Java中声明异常相同的文档属性,它们只是不同的方法,但通常更好的方法是使用更适合手头语言的方法,除非有非常令人信服的理由不这样做。 / p>