2012-12-28 48 views
3

可能重複:
does code in finally get run after a return in objective-c?如果在catch塊中拋出異常,是否會執行finally塊?

考慮目標C僞代碼的此塊:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

@try { 
    throw [[NSException alloc] init]; 
} 
@catch (NSException *e) { 
    throw e; 
} 
@finally { 
    [pool drain]; 
} 

將池倒掉?或者@catch塊中的throw呈現該代碼無法訪問?我覺得池應該被耗盡,但我無法以這種或那種方式找到它的文檔。

是的,我可以寫一些代碼並測試它,但目前不可行。

感謝

+2

@Perception這可能重複不回答這個問題。該問題和文檔清楚地表明finally子句在try塊中是否存在異常,但沒有提及如果從catch塊拋出異常會發生什麼。它可能被稱爲,但另一個問題並沒有澄清這個問題。 – rmaddy

+0

@Madbreaks從Eugene鏈接的文檔看來,您應該調用「@throw」而不是「throw e」來重新拋出異常。如果你這樣做的話,這個文檔暗示(儘管沒有明確說明)「終於」會被調用。 – rmaddy

+0

請注意,您絕對不應該爲了從中恢復而捕獲異常。在iOS和OS X中,異常僅用於指示不可恢復的錯誤(只有極少數可憐的奇數情況)。 – bbum

回答

4

Yes (docs)

與本地@catch異常處理程序 相關聯的@finally塊@throw導​​致下一個較高的異常處理程序 要被調用之前執行。

有關內存管理的進一步說明,請參閱鏈接文檔頁面的底部。在你的例子中你是「OK」,因爲這個異常本身並不是自動釋放的,因爲你的finally塊中正在耗盡的池的一部分。但是如果沒有人釋放它,你可能會泄露該異常。

(但似乎有大約在某些情況下例外生命週期的某些不確定性,請參閱:What is the lifecycle of an object caught in a @catch block?

+0

謝謝 - 這是我見過的最令人放心的文檔(顯然我沒有看到這一切)。我覺得其他地方的文檔只討論'try'塊中提出的異常,這就是爲什麼我很難接受真相。 – Madbreaks

+0

@Eugene發佈的示例程序是否與此相矛盾? – Madbreaks

+1

@Madbreaks否 - 他的示例應用程序在記錄器有機會打印到控制檯之前就會死亡,並顯示未處理的異常。如果您使用相同的示例,但是從另一個try/catch中調用它,則會看到打印出的「finally」日誌。 –

2

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Exceptions/Tasks/HandlingExceptions.html

@finally — Defines a block of related code that is subsequently executed whether an exception is thrown or not.

但完全沒有談到catch塊例外。 這聽起來合乎邏輯,這個例外不會有問題。

我做了簡單的程序來檢查:

import <Foundation/Foundation.h> 

int main(int argc, char **argv) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init] ; 

    int result = 0 ; 

    @try { 
      @throw [NSException exceptionWithName:@"Exception" reason:@"@try" userInfo:nil]; 
    } 
    @catch (id exception) { 
      @throw [NSException exceptionWithName:@"Exception" reason:@"@catch" userInfo:nil]; 
    } 
    @finally { 
      NSLog(@"Finally"); 
    } 

    [pool release] ; 
    return result ; 
} 

簡單地編譯和執行:

$ gcc -framework Foundation -fobjc-exceptions test.m 
$ ./a.out 
2012-12-29 00:39:21.667 a.out[86205:707] *** Terminating app due to uncaught exception 'Exception', reason: '@catch' 
*** First throw call stack: 
(
    0 CoreFoundation      0x00007fff8e3050a6 __exceptionPreprocess + 198 
    1 libobjc.A.dylib      0x00007fff8e56e3f0 objc_exception_throw + 43 
    2 a.out        0x0000000107d48d47 main + 359 
    3 libdyld.dylib      0x00007fff90b4e7e1 start + 0 
) 
libc++abi.dylib: terminate called throwing an exception 
Abort trap: 6 
+0

看到,但我不相信這是報價說的。我相信這句話是說''finally'塊會被執行,無論'try'塊中是否拋出異常。接受它作爲基於這句話的真相對我來說是一個灰色地帶。 – Madbreaks

+0

@BenZotto我已經糾正了答案。在原始問題中丟失了關於catch block的部分 – Ievgen

+0

_「聽起來合乎邏輯的是,這個異常不會發生」,對,它不會。這不是我要問的。我問是否(在你的例子中)'「Finally」將被記錄或不記錄。 – Madbreaks

相關問題