2017-02-09 6 views
4

Objective-C 범주에서이 흥미로운 코드를 발견했습니다.이 범주는 NSExceptions를 잡아 내고이를 Swift 코드에 NSErrors로 전달하는 데 사용됩니다.Objective-C try-catch - 왜 이것을 컴파일합니까? 그리고 왜 다른 반환 디버그 대 릴리스 디버그입니까?

내가 이해할 수없는 내용은 다음과 같습니다. 1) 컴파일하는 이유는 무엇입니까? 예외가 발생하면 반환 값이 없습니다. 2) 디버그 (최적화 레벨 없음) 및 릴리스 (최적화 레벨 최소/가장 빠름)로 컴파일 할 때 반환 값이 다른 이유는 무엇입니까?

- (BOOL)catchException:(void(^)())tryBlock error:(__autoreleasing NSError **)error { 
    @try { 
     tryBlock(); 
     return YES; 
    } 
    @catch (NSException *exception) { 
     NSMutableDictionary *userInfo = [exception.userInfo mutableCopy]; 
     if (!userInfo) userInfo = [NSMutableDictionary new]; 
     userInfo[NSLocalizedDescriptionKey] = exception.reason; 
     *error = [[NSError alloc] initWithDomain:exception.name code:0 userInfo:userInfo]; 
    } 
    // Note the missing return value outside the try-catch 
} 

함수를 호출 : 컴파일 및 디버그 방식으로 실행하는 경우

NSError *error; 
BOOL result = [self catchException:^{ 
    @throw [NSException exceptionWithName:@"Exception" reason:@"WTF?" userInfo:nil]; 
} error:&error]; 

NSLog(@"Result: %@", result ? @"YES" : @"NO"); 

을, 우리가 얻을 :

:

2017-02-09 10:01:39.695 Compile Test[23129:630118] Result: NO 

그리고 릴리스 방식과 같은 일을 할 때

2017-02-09 10:01:39.695 Compile Test[23129:630118] Result: YES 

따라서 try-catch 블록 외부에 반환 값이 없으며 try-catch 내부의 반환 값에 도달하지 못하더라도 두 경우 모두 반환 값이 나타납니다. 우리 모두 여기 혼동스러워?!

+0

Apple에 버그 리포트를 제출했습니다. 그 이상의 문제가 있습니다. –

+0

버그 신고 해주셔서 감사합니다! – bbum

답변

3

이것은 컴파일러 버그 또는 "반환 값이 있는지 확인하는 제어 흐름 검사"옵션 (있는 경우)이 해제되어 있습니다.

동작이 정의되지 않았기 때문에 반환 값이 다릅니다.

기본적으로 스택에있을 가능성이있는 레지스터는 대상 CPU의 ABI에 따라 스택에있을 수 있습니다. 함수가 반환 할 때 반환 값을 보유합니다.

최적화하지 않으면 컴파일러에서 레지스터와 스택을 다시 사용하지 않습니다. 모든 변수는 자체 공간을 가지며 함수의 끝까지 보존됩니다. 최적화를 통해 컴파일러는 메모리를 사전에 재사용하여 동작을 변경합니다. 이것은 최적화 된 코드를 디버깅하는 것이 그렇게 고통스러운 이유이기도합니다. 'p myVariable'은 'myVariable'이 재활용 되었기 때문에 예기치 않은 것을 인쇄 할 수 있습니다.

+0

감사합니다. 이것은 분명히 정의되지 않은 반환 값 수수께끼를 설명합니다. 아직도 컴파일이 어려우므로 컴파일러가'return ...'문을'@try {...} '영역 밖에서 제시해야한다고 생각했습니다. 이 경우 리턴 유형이 무엇인지는 중요하지 않은 것처럼 보이지만 컴파일러는 대체 리턴 값이 지정되지 않았 음을 신경 쓰지 않습니다. 그러나, 결국 귀하의 설명은 최종적으로 반환되는 것의 측면에서 의미가 있습니다. –