为什么这个Objective C调用似乎挂起?

Mit*_*ren 6 objective-c hang undefined-behavior

我的一个朋友在NSDictionary中发现了一些奇怪的行为,我很好奇它为什么会发生.请考虑以下代码:

NSDictionary *dict = [[NSDictionary alloc] init];

// Oops, we can't mutate an NSDictionary
[dict setObject:[[NSNull alloc] init] forKey:@"test"];
NSLog(@"Set");
Run Code Online (Sandbox Code Playgroud)

代码在编译时会产生警告"'NSDictionary'可能不响应'setObject:forKey:'".这一切都很好,如果你还是运行它,你将在控制台中得到这个输出:

- [__ NSCFDictionary setObject:forKey:]:将mutating方法发送到不可变对象

再次,正是你期望发生的事情.但是,此时应用程序不会因未捕获的异常而崩溃或终止.setObject:forKey:方法根本不会返回,应用程序似乎挂起; 以下NSLog内容从未执行过.如果您尝试使用GDB跳过或进入该方法,调试似乎结束,但没有任何明确的错误消息.该应用程序继续运行,但调试器没有提供代码中执行"卡住"的位置的线索.

这里发生了什么?在这种情况下,应用程序实际上做了什么,为什么它不会因为NSInternalInconsistencyException或类似的东西而崩溃?

编辑:对于那些曾经问过的人,我在OS X Lion(10.7.2)上运行XCode 4.1,使用"Apple LLVM编译器2.1"构建.我正在使用XCode 4中新的Cocoa项目获得的所有默认设置.无论是调试程序还是"运行",我都会遇到相同的非崩溃行为.从Debug构建更改为Release构建没有任何区别.我甚至可以在Finder中手动找到.app文件并双击它以在XCode之外执行它,它仍然不会崩溃.

Bor*_*aut 1

异常不会导致 AppKit 程序崩溃。NSApplication 安装一个默认的异常处理程序,用于捕获代码未捕获的异常。然后你就像平常一样回到运行循环。

许多应用程序都表现出这种行为。这是导致无法解释的空白视图/窗口的常见原因。如果在视图完成绘制之前发生异常,则视图将为空白,但应用程序不会崩溃。如果您故意将默认异常处理程序更改为崩溃,则异常只会导致崩溃。