Re: Years-old mysterious bindings crash
Re: Years-old mysterious bindings crash
- Subject: Re: Years-old mysterious bindings crash
- From: Seth Willits <email@hidden>
- Date: Wed, 05 Oct 2011 15:49:33 -0700
Ok, this is long but I think I've maybe found an answer to something. I'm guessing I'm somehow rarely triggering a bug in Cocoa.
I've had a couple of these exceptions, and this may be more helpful. So [AQConnTabController initWithNibName:bundle:windowController:] creates a NSObjectController, with nil content. Then it calls [self view] to load the nib. The object controller later on in awakeFromNib is given some content and then much much later, eventually some things bind to the object controller's selection.isProcessing key path. So during the loading of the nib, nothing is bound to the object controller at all.
I stuck a breakpoint on setContent: and fired up my app and it's when loading this nib it's never called, except when the NSObjectController is allocated (with a nil content), and when I call setContent: from awakeFromNib. It's never called elsewhere so I'm strongly imaginging that there *should* be a -[AQConnTabController awakeFromNib] line between nibInstantiateWithOwner:topLevelObjects: and the setContent: in the stack trace below, but it's not showing up because it's a tail call or something. It doesn't make sense any other way.
So now the interesting part is, in the exception below, it's firing off a selection.isProcessing KVO message while the nib is loading. Nothing in the nib is at all bound or connected to the object controller that has selection.isProcessing on it. So this lends support to the idea that KVO has a deallocated object still registered as an observer for selection.isProcessing.
What I'm imaging happened in this case is that the new object controller was allocated using the same pointer as an old controller. That old controller was deallocated, the old observer was deallocated, but somehow there is still a KVO record for the observer being registered for that keypath on an object with that pointer. So when this new object controller is created, and its setContent: is set to a new content object, it looks in the KVO table, finds it has an observer registered with it and attempts to notify it. It throws an exception however because the new object which happens to exist at the old observer's pointer (which is now the NSThemeFrame in this particular example) isn't actually an observer and thus throws this exception.
That seems to make sense, but I don't know how it's possible for both the observer and observee to be deallocated, and the KVO registration to still exist.
I took a look at the code and I discovered I'm adding an object as an observer of selection.isProcessing on the object controller, but not removing that registration. I can confirm that the object controller and the observer are both being deallocated, but interestingly, I'm not getting that normal KVO warning that the object controller is being deallocated while some object is still observing it.
I don't know how this all fits together, but it seems like 1 in a 1,000 times, this causes an exception or crash later on. Seems plausible. At any rate, I'll remove the observer and then keep an eye out for any new crash logs; If I get one, then this wasn't related. :\
Thanks for the feedback, guys.
<NSThemeFrame: 0x116b9f5a0>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: selection.isProcessing
Observed object: <NSObjectController: 0x1181b42a0>[object class: NSMutableDictionary]
Change: {
kind = 1;
}
Context: 0x0
__exceptionPreprocess + 180
objc_exception_throw + 45
+[NSException raise:format:arguments:] + 103
+[NSException raise:format:] + 148
-[NSObject(NSKeyValueObserving) observeValueForKeyPath:ofObject:change:context:] + 69
NSKeyValueNotifyObserver + 338
-[NSObject(NSKeyValueObservingPrivate) _notifyObserversForKeyPath:change:] + 991
-[NSController _notifyObserversForKeyPath:change:] + 218
-[NSObjectController setContent:] + 369
-[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1515
-[NSNib instantiateNibWithExternalNameTable:] + 564
-[NSNib instantiateNibWithOwner:topLevelObjects:] + 233
-[NSViewController loadView] + 180
-[NSViewController view] + 38
-[AQConnTabController initWithNibName:bundle:windowController:] + 801
-[AQConnWindowController newTab:] + 56
-[NSWindowController _windowDidLoad] + 538
-[NSWindowController window] + 112
-[NSWindowController showWindow:] + 47
-[AQController newConnectionWindow:] + 72
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden