2012-12-28 7 views
3

가능한 중복 :catch 블록에서 예외가 발생하면 finally 블록이 실행됩니까?

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

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

가 풀을 고갈됩니다
does code in finally get run after a return in objective-c?

가 목적 C의 의사 코드의 블록을 고려? 또는 @catch 블록의 throw이 해당 코드를 도달 할 수 없게 만듭니다. 나는 수영장을 느낀다 는 물기가 있어야한다. 그러나 나는 그것에 대한 문서를 찾을 수 없다.

예 코드를 작성하고 테스트해볼 수는 있지만 현재로서는 불가능합니다.

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

+2

@Perception을 중복 가능성이 질문에 대답하지 않습니다. 이 질문과 문서는 try 블록에 예외가 있는지 없는지 여부에 관계없이 finally 절을 호출하지만 catch 블록에서 예외가 발생할 경우 어떤 일이 발생하는지에 대해서는 언급하지 않았습니다. 그것은 부름을받을 수 있지만, 다른 질문은이 질문을 명확히하지 않습니다. – rmaddy

+0

@Madbreaks Eugene에서 링크 된 문서에서 "throw e"대신 "@throw"를 호출하여 예외를 다시 발생시켜야합니다. 문서를 보면 일종의 "finally"가 호출된다고 명시되어 있습니다. – rmaddy

+0

복구를 위해 예외를 포착해서는 안됩니다. iOS 및 OS X에서 예외는 복구 할 수없는 오류 만 표시하는 데 사용됩니다 (극히 소수의 좋지 않은 경우가 있음). – bbum

답변

4

Yes (docs)합니다. @throw 호출 될 다음 높은 - 예외 핸들러 가 발생하기 전에

로컬 @catch 예외 핸들러 와 연관된 @finally

블록이 실행된다.

이 경우 메모리 관리에 대한 자세한 내용은 링크 된 문서 페이지의 맨 아래 부분을 참조하십시오. 귀하의 예제에서는 "OK"입니다. 왜냐하면 예외가 자체적으로 최종 블록에있는 풀의 일부로 자동으로 리사이즈되지 않기 때문입니다. 그러나 아무도 그것을 풀어주지 않으면 그 예외를 유출 할 수 있습니다.

이 (그러나 어떤 경우에는 예외 라이프 사이클의 주위에 약간의 모호함있을 것 같습니다, 참조 : What is the lifecycle of an object caught in a @catch block?를)

+0

감사합니다. 내가 본 모든 문서 중에서 가장 안심할 수있는 문서입니다. 나는 다른 곳의 문서가'try' 블록에서만 발생한 예외에 대해 이야기한다고 생각합니다. 그래서 나는 단순히 진실을 받아들이는 것이 힘들었습니다. – Madbreaks

+0

@Eugene이 게시하지 않은 샘플 프로그램이이 사실을 모순하는 것처럼 보입니까? – Madbreaks

+1

@Madbreaks 아니요 - 그의 예제 앱은 로거가 콘솔로 출력하기 전에 처리되지 않은 예외로 죽습니다. 동일한 예제를 사용하지만 다른 try/catch에서 호출하면 "finally"로그가 출력됩니다. –

2

:

@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 블록에 관한 부분을 잃어 버림 – Ievgen

+0

_ "이 예외가 발생하지 않는다는 것이 논리적 인 것처럼 들리네"_, 맞습니다. 그건 내가 묻는 것이 아니다. 나는 (당신의 예제에서)''Finally''가 로깅되는지 아닌지 물어볼 것입니다. – Madbreaks

관련 문제