ios - 为什么此 Objective C 代码会因 EXC_BAD_ACCESS code=1 而崩溃? (使用 block 语法和字典)

标签 ios objective-c nsdictionary objective-c-blocks

//Section 1 (declarations)    

NSString *foo;
NSString *bar;

NSDictionary *foobar =
@{
    @"bar":^{return @"foo";}
 };
typedef NSString *(^barfoo)();

鉴于上述声明,为什么只生成以下 Objective-C 代码的最后一行

EXC_BAD_ACCESS code=1

//Section 2 (crashes)

foo = foobar[@"bar"];             //no error, foo == @"foo"
bar = foobar[@"foo"];             //no error, bar == nil
foo = ((barfoo)foobar[@"bar"])(); //no error, foo == @"foo"
bar = ((barfoo)foobar[@"foo"])(); //EXC_BAD_ACCESS code=1
NSLog(@"%@%@",foo,bar);           // never runs!

我应该注意到,在 try/catch 中,catch 不会捕获任何东西;没有异常被抛出。将 foobar 的内容更改为 @{@"bar":^NSString*{return @"foo";} 没有帮助。

我还应该注意到以下代码有效并且没有错误:

//Alternate Section 2 (does not crash)    

barfoo foobard = foobar[@"foo"];
barfoo barfood = foobar[@"bar"];
barfood ? foo = barfood() : nil;
foobard ? bar = foobard() : nil;
NSLog(@"%@%@",foo,bar);          // Returns foo(null)

注意:代码在 iOS 9.2.1 上执行。

最佳答案

我很困惑为什么会感到困惑。

由于 foobar[@"foo"]nil(正如您的评论正确显示的那样),您不能将其视为一个 block 并调用它。这就是 ((barfoo)foobar["@foo"])() 崩溃的原因。

当第二个代码段检测到你从字典中得到的对象是 nil 时,它根本不调用任何东西,因此它对 foobar[@"foo"] 的返回没有任何作用

关于 try catch - 它不会抛出错误,它崩溃。那是不同的东西。程序无法恢复的东西。您作为开发人员必须确保不会发生的事情。您的工作是确保您尝试调用的 block 实际上是非nil

关于ios - 为什么此 Objective C 代码会因 EXC_BAD_ACCESS code=1 而崩溃? (使用 block 语法和字典),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34907459/

相关文章:

IOS:从 JSON 中检测 NSNull 不起作用

iOS - 静默推送后我需要处理时间

ios - 使用核心数据谓词进行身份验证后获取用户名

ios - [myclass encodeWithCoder:]:使用NSUserDefaults时,无法识别的选择器发送到实例错误

ios - 将字典存储到 Firebase 中?

ios - 方法未在协议(protocol)中实现(使用 wit.ai SDK)

ios - 如何配置我的 EarlGrey 测试以等待 View 或事件?

ios - 为什么我的 CGPoints 全部返回为 {0,0}?

objective-c - Cocoa Accessibility API 消耗鼠标点击

iphone - U_ILLEGAL_ARGUMENT_ERROR 导致我的应用程序崩溃