为什么此 Objective C 代码会因 EXC_BAD_ACCESS 代码=1 而崩溃? (使用块语法和字典)
Why does this Objective C code crash with EXC_BAD_ACCESS code=1? (Uses block syntax and dicts)
//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
(正如您的评论正确显示的那样),您不能将其视为一个块并调用它。这就是 ((barfoo)foobar["@foo"])()
崩溃的原因。
当第二个代码段检测到您从字典中获得的对象是 nil
时,它根本不调用任何东西,因此它对 foobar[@"foo"]
[= 的 return 没有任何作用17=]
关于 try catch
- 它不会抛出错误,它 崩溃 。那是不同的东西。程序无法恢复的东西。您作为开发人员必须确保不会发生的事情。您的工作是确保您尝试调用的块实际上是非 nil
.
//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
(正如您的评论正确显示的那样),您不能将其视为一个块并调用它。这就是 ((barfoo)foobar["@foo"])()
崩溃的原因。
当第二个代码段检测到您从字典中获得的对象是 nil
时,它根本不调用任何东西,因此它对 foobar[@"foo"]
[= 的 return 没有任何作用17=]
关于 try catch
- 它不会抛出错误,它 崩溃 。那是不同的东西。程序无法恢复的东西。您作为开发人员必须确保不会发生的事情。您的工作是确保您尝试调用的块实际上是非 nil
.