简体   繁体   English

Objective-C try-catch - 为什么编译? 为什么返回不同的构建调试与发布?

[英]Objective-C try-catch - why does this compile? And why is the return different building debug vs release?

Found this interesting bit of code in an Objective-C category which is used to catch NSExceptions and pass them as NSErrors to Swift code. 在Objective-C类别中找到了这个有趣的代码,用于捕获NSExceptions并将它们作为NSErrors传递给Swift代码。

What I don't understand about it is: 1) Why does it even compile? 我不明白的是:1)为什么甚至编译? If an exception is thrown, there is never a return value. 如果抛出异常,则永远不会有返回值。 2) Why is the return value different when compiling with debug (optimization level none) and with release (optimization level smallest/fastest)? 2)为什么在使用debug(优化级别none)和release(优化级别最小/最快)进行编译时返回值会有所不同?

- (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
 }

Invoking the function: 调用函数:

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

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

When compiling and running with the Debug scheme, we get: 在使用Debug方案进行编译和运行时,我们得到:

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

And when doing the same with the Release scheme: 在使用Release方案时也是如此:

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

So in both cases there appears to be a return value, even though there is no returned value outside the try-catch block, and the return value inside the try-catch is never reached. 因此,在这两种情况下都会出现返回值,即使try-catch块之外没有返回值,也永远不会达到try-catch中的返回值。 We're all very confused over here ?! 我们都在这里很困惑?!

That is either a compiler bug or the "check control flow to make sure return value is present" option is turned off (if there is one). 这是编译器错误或“检查控制流以确保返回值存在”选项被关闭(如果有)。

The differing return value is because the behavior is undefined. 不同的返回值是因为行为未定义。

Basically, whatever happens to be in the slot -- likely a register, might be on the stack, depends on the ABI of the targeted CPU -- that holds the return value at the time the function returns will be used. 基本上,无论发生在插槽中的什么 - 可能是寄存器,可能在堆栈上,取决于目标CPU的ABI - 在函数返回时保存返回值将被使用。

Without optimization, the compiler won't reuse registers and the stack; 如果没有优化,编译器将不会重用寄存器和堆栈; every variable gets its own space and it is preserved to the end of the function. 每个变量都有自己的空间,并保存到函数的末尾。 With optimization, the compiler will reuse memory proactively, causing the behavior change. 通过优化,编译器将主动重用内存,从而导致行为更改。 This is also why debugging optimized code is such a pain; 这也是调试优化代码如此痛苦的原因; 'p myVariable' might print something unexpected simply because 'myVariable' has been recycled. 'p myVariable'可能会打印出意想不到的东西,因为'myVariable'已被回收。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM