在什么情况下,在Cocoa的try / catch / finally异常处理中@finally是非冗余的?

时间:2009-04-12 10:09:52

标签: objective-c cocoa exception exception-handling try-catch

考虑以下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在什么情况下是非冗余的?

5 个答案:

答案 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)

当:

  • 您没有发现发生的异常类型
  • 您捕获了异常,但catch块中的代码也引发异常。

答案 4 :(得分:0)

一个较低级别的问题,你为什么要这样做?

try / catch / finally方法在Java中被广泛使用,但几乎没有在Objective-C中使用,并且不是首选方法 - 您根本不需要它,因为库不会像Java库调用那样抛出异常,如果您正在编写自己的库,那么您不应期望调用者会自然地想要查找要捕获的异常。

最广泛使用和理解的约定是具有错误方法回调的委托,或者可能需要通过多级代码传递的更常见故障的通知。如果有一个简单的通知系统,那么这种方法可能会在Java世界中得到更广泛的应用。

委托方法具有与在Java中声明异常相同的文档属性,它们只是不同的方法,但通常更好的方法是使用更适合手头语言的方法,除非有非常令人信服的理由不这样做。 / p>