我的一个朋友发现了NSDictionary的一些奇怪的行为,我很好奇它为什么会发生。请考虑以下代码:
NSDictionary *dict = [[NSDictionary alloc] init];
// Oops, we can't mutate an NSDictionary
[dict setObject:[[NSNull alloc] init] forKey:@"test"];
NSLog(@"Set");
代码在编译时产生警告“'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之外执行它,它仍然不会崩溃。
答案 0 :(得分:1)
异常不会导致AppKit程序崩溃。 NSApplication安装一个默认的异常处理程序,用于捕获代码不能处理的异常。然后你就像往常一样回到runloop。
许多应用都表现出这种行为。这是莫名其妙的空白视图/窗口的常见原因。如果在视图设法完成绘制之前发生异常,则视图将为空,但应用程序不会崩溃。如果您故意将默认异常处理程序更改为崩溃,则异常只会导致崩溃。