我的一个朋友在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之外执行它,它仍然不会崩溃.
这个问题来自于我的另一个问题,即为什么我的应用程序没有被例外打倒.
问题
当通过Action在主线程上抛出异常时,应用程序仍然不会崩溃.
根据Dave对原始问题的回答,我在NSApplication上实现了reportException类,并设置了未捕获的异常处理程序.
码
我在我的app委托中有以下内容,我已经连接到我的UI中的一个按钮进行测试.
-(IBAction)crashOnMainThread:(id)sender {
[self performSelectorOnMainThread:@selector(crash) withObject:nil waitUntilDone:YES];
}
-(void)crash {
// To test out the exception handling
[NSException raise:NSInternalInconsistencyException format:@"This should crash the app."];
}
Run Code Online (Sandbox Code Playgroud)
当我按下按钮时,我的应用程序不会崩溃.当我查看控制台日志时,我看到了:
06/09/2010 14:12:25 EHTest1[26384] HIToolbox: ignoring exception 'This should crash the app.' that raised inside Carbon event dispatch
(
0 CoreFoundation 0x00007fff80ab4cc4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff819560f3 objc_exception_throw + 45
2 CoreFoundation 0x00007fff80ab4ae7 +[NSException raise:format:arguments:] + 103
3 CoreFoundation 0x00007fff80ab4a74 +[NSException raise:format:] + 148
4 …Run Code Online (Sandbox Code Playgroud)