繁体   English   中英

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

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

在Objective-C类别中找到了这个有趣的代码,用于捕获NSExceptions并将它们作为NSErrors传递给Swift代码。

我不明白的是:1)为什么甚至编译? 如果抛出异常,则永远不会有返回值。 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
 }

调用函数:

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

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

在使用Debug方案进行编译和运行时,我们得到:

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

在使用Release方案时也是如此:

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

因此,在这两种情况下都会出现返回值,即使try-catch块之外没有返回值,也永远不会达到try-catch中的返回值。 我们都在这里很困惑?!

这是编译器错误或“检查控制流以确保返回值存在”选项被关闭(如果有)。

不同的返回值是因为行为未定义。

基本上,无论发生在插槽中的什么 - 可能是寄存器,可能在堆栈上,取决于目标CPU的ABI - 在函数返回时保存返回值将被使用。

如果没有优化,编译器将不会重用寄存器和堆栈; 每个变量都有自己的空间,并保存到函数的末尾。 通过优化,编译器将主动重用内存,从而导致行为更改。 这也是调试优化代码如此痛苦的原因; 'p myVariable'可能会打印出意想不到的东西,因为'myVariable'已被回收。

暂无
暂无

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

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