Tuesday, January 3, 2012
I've been dancing with this bug for the past day and a half. Now that I found the problem, I thought I'd detail it here for anyone else having the issue to find in the future.
The problem I've found is that, on Lion, after opening a document represented by a NSDocument subclass, the app would crash. This did not occur for any NSDocument subclass, just one in particular. It would report an uncaught exception to me with the following stack trace:
2012-01-02 16:04:03.405 Pear Note[5933:507] An uncaught exception was raised 2012-01-02 16:04:03.406 Pear Note[5933:507] *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil 2012-01-02 16:04:03.409 Pear Note[5933:507] ( 0 CoreFoundation 0x00007fff94eb1286 __exceptionPreprocess + 198 1 libobjc.A.dylib 0x00007fff8dd6bd5e objc_exception_throw + 43 2 CoreFoundation 0x00007fff94e58108 -[__NSArrayM insertObject:atIndex:] + 296 3 AppKit 0x00007fff970e475d __-[NSApplication(NSAppleEventHandling) _handleAEOpenDocumentsForURLs:]_block_invoke_2 + 1089 4 AppKit 0x00007fff971e9ca7 __-[NSDocumentController _openDocumentsWithContentsOfURLs:presentErrors:completionHandler:]_block_invoke_2 + 50 5 Foundation 0x00007fff8f835b95 -[NSBlockOperation main] + 116 6 Foundation 0x00007fff8f7fc788 -[__NSOperationInternal start] + 705 7 Foundation 0x00007fff8f80f9e6 ____NSOQSchedule_block_invoke_2 + 124 8 libdispatch.dylib 0x00007fff961f78ba _dispatch_call_block_and_release + 18 9 libdispatch.dylib 0x00007fff961f972a _dispatch_main_queue_callback_4CF + 308 10 CoreFoundation 0x00007fff94e464dc __CFRunLoopRun + 1724 11 CoreFoundation 0x00007fff94e45ae6 CFRunLoopRunSpecific + 230 12 HIToolbox 0x00007fff918793d3 RunCurrentEventLoopInMode + 277 13 HIToolbox 0x00007fff9188063d ReceiveNextEventCommon + 355 14 HIToolbox 0x00007fff918804ca BlockUntilNextEventMatchingListInMode + 62 15 AppKit 0x00007fff96e273f1 _DPSNextEvent + 659 16 AppKit 0x00007fff96e26cf5 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 135 17 AppKit 0x00007fff96e2362d -[NSApplication run] + 470 18 AppKit 0x00007fff970a280c NSApplicationMain + 867 19 Pear Note 0x000000010001a172 main + 34 20 Pear Note 0x00000001000021b4 start + 52 )
This is a fun stack trace, as it contains none of my code. But, it at least gave the clue that something was nil that Cocoa couldn't handle. So, I began searching for what this missing object might be.
First I looked for methods I had overridden that might be giving back nil when they shouldn't. That yielded nothing. Then I tried overriding other methods in NSDocument just to see if any of them were returning nil. Nope. Then I moved on to NSDocumentController. Nothing. I couldn't find anything in my code that could be causing the problem.
Finally, I discovered the problem. It wasn't in my code at all, but rather in the xib file for the document. I had not connected (or more likely had disconnected) the window outlet for my NSDocument from the window. This NSDocument subclass often didn't even need a window (as it was used as a temporary object for importing other data types into a proper Pear Note document). So, the simple solution was to connect this outlet to a window. Problem solved.
Of course, this is technically Apple's bug. They shouldn't be crashing because of this, or at least should be checking input to provide a useful error message before crashing. So, being a good citizen I've submitted a bug to Apple. If you'd like to dup it, it's rdar://10638416.