A friend of mine discovered some strange behaviour with NSDictionary, and I'm curious as to why it happens. Consider the following code:
NSDictionary *dict = [[NSDictionary alloc] init];
// Oops, we can't mutate an NSDictionary
[dict setObject:[[NSNull alloc] init] forKey:@"test"];
NSLog(@"Set");
The code produces a warning upon compilation that "'NSDictionary' may not respond to 'setObject:forKey:'". That's all well and good, and if you run it anyway, you'll get this output in the console:
-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object
Again, exactly what you'd expect to happen. However, at this point the app does not crash or terminate due to an uncaught exception. The setObject:forKey: method simply never returns, and the app appears to hang; the following NSLog
is never executed. If you try to step over or into the method using GDB, debugging just seems to end, but without any explicit error message. The app continues to run, but the debugger provides no clue as to where in the code the execution is "stuck."
What's going on here? What is the app actually doing in this case, and why doesn't it crash with an NSInternalInconsistencyException or something of the like?
Edit: For those who have asked, I'm running XCode 4.1 on OS X Lion (10.7.2), building with "Apple LLVM compiler 2.1." I'm using all of the default settings you get with a new Cocoa project in XCode 4. I experience the same non-crashing behaviour regardless of whether I debug the program or just "Run" it. Changing from Debug building to Release building makes no difference. I can even locate the .app file manually in Finder and double click on it to execute it outside of XCode, and it still does not crash.