Re: KVO problems popping up in Leopard
Re: KVO problems popping up in Leopard
- Subject: Re: KVO problems popping up in Leopard
- From: "Doug Knowles" <email@hidden>
- Date: Sun, 18 Nov 2007 19:37:58 -0500
Hi, Dave,
Thanks for your help; I've been poking at this some more, following your
advice and a couple of other threads for the last couple of days.
As luck would have it, I was already tracking the registered observers of my
proxy objects, so I was able to determine that there is one observer of the
property in question at the time of the bad access exception, and it is
still valid, but the associated context looks suspicious - I get a debugger
crash when I try to examine it after the exception:
2007-11-16 08:29:08.388 SLNavigator[2102:813] @@@ LVProxyLinkedItem
0xcda1ad0 adding observer (<NSKeyValueObservance 0xcda8300: Observer:
0xcd65450, Key path: representedObject.lvName, Options: <New: NO, Old: NO,
Prior: NO> Context: 0xa05a028c, Property: 0xcd6e6d0>) for key path: lvName
...
2007-11-16 08:29:13.540 SLNavigator[2102:813] DEBUG: -[ListViewItemProxy
willChangeValueForKey:] for lvName
Program received signal: "EXC_BAD_ACCESS".
(gdb) po 0xcda8300
<NSKeyValueObservance 0xcda8300: Observer: 0xcd65450, Key path:
representedObject.lvName, Options: <New: NO, Old: NO, Prior: NO> Context:
0xa05a028c, Property: 0xcd6e6d0>
(gdb) po 0xcd65450
<NSOutlineViewBinder: 0xcd65450>{object: <ListOutlineView: 0xcd426c0>,
bindings: content=arrangedObjects, selectionIndexPaths=selectionIndexPaths,
sortDescriptors=sortDescriptors}
(gdb) po 0xa05a028c // <-- [Context field of the
NSKeyValueObservance object above]
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000020
0x92f646e8 in objc_msgSend ()
The program being debugged was signaled while in a function called from GDB.
GDB has restored the context to what it was before the call.
To change this behavior use "set unwindonsignal off"
Evaluation of the expression containing the function (_NSPrintForDebugger)
will be abandoned.
On a subsequent run, I examined the same "context" value at the time the
observer was registered:
*(gdb) **po 0xcd6efa0*
<NSKeyValueNestedProperty: Container class: NSTreeControllerTreeNode,
Relationship property: <NSKeyValueUnnestedProperty: Container class:
NSTreeControllerTreeNode, Key: representedObject, isa for autonotifying:
NSKVONotifying_NSTreeControllerTreeNode, Key paths of directly and
indirectly affecting properties: none>, Key path from related object:
lvName>
...but I don't see why I'm getting the crash in objc_msgSend if the problem
is a member of the object being messaged.
The other things I'm looking at are liberties I take with the KVO protocol:
- My proxy objects implement valueForUndefinedKey: and
setValue:forUndefinedKey: to present properties derived from the model
objects they represent;
- they also invoke will... and didChangeValueForKey: on these "undefined"
keys to trigger refresh of the derived values;
- the property in question, "lvName", is one of these derived values; since
I encountered this problem, I implemented accessors for this property so
that it wouldn't pass through the undefined key methods, but it is still a
"non-standard" KVO property.
Thanks for the advice so far...
Doug K;
On Nov 15, 2007 2:19 AM, David Spooner <email@hidden> wrote:
> Doug,
>
> Most likely your proxy is trying to notify an observer which has been
> deallocated, so the deallocated object has not removed it's
> observation for whatever reason.
>
> You might get more information by enabling zombies.
>
> A brute-force approach to locating the culprit is to override the kvo
> methods -addObserver:... and -removeObserver:... in your proxy class
> and log the observer's class name and address. Try to reduce the
> number of log messages by restricting attention to a specific key and
> a specific receiver; use a global variable to mark a single proxy
> object, setting its value explicitly in gdb or in your code as the
> first receiver of -addObserver:...
>
> You may be able to see the address of the deallocated object as the
> first argument to objc_msgSend. If not, use 'po' to check that the
> objects with registered observations are still valid. If you find a
> deallocated object of a class you recognize, ensure that it is
> properly removing observations. If the deallocated object is an
> NSKeyValueForwarder (or whatever) then likely an observation is being
> established on a key path and some object in the path is not
> generating key/value notification on property changes.
>
> Hope this helps,
>
> dave
>
>
> On 14-Nov-07, at 8:01 PM, Doug Knowles wrote:
>
> > Hi, all,
> >
> > The app I've been working on is suddenly very broken under Leopard.
> > The
> > most severe problem right now occurs when I edit a column cell in an
> > NSOutlineView: on committing the changes, I get an EXC_BAD_ACCESS,
> > apparently related to a notification to the object whose value is
> > being
> > edited.
> >
> > The NSTreeController is in class mode, binding to "proxy" objects
> > that I set
> > up between the controller and the underlying Core Data objects. The
> > error
> > occurs when I try to commit a change in a column bound to a property
> > on the
> > proxy object; specifically, according to the stack trace, when
> > attempting to
> > invoke "willChangeValueForKey:" for the modified property. I've made
> > several changes to the code to try to clean it up and/or instrument
> > it;
> > here's a current stack trace (annotated):
> >
> > #0 0x92f646e8 in objc_msgSend
> > #1 0x94fac880 in NSKVOPendingNotificationCreate
> > #2 0x94f2958d in -[NSObject(NSKeyValueObserverNotification)
> > willChangeValueForKey:]
> > #3 0x000315e4 in -[ListViewItemProxy willChangeValueForKey:] at
> > ListViewItemProxy.m:487
> > (this is an instrumentation method I added to figure out which
> > property
> > is involved...)
> > #4 0x94fac2ed in _NSSetObjectValueAndNotify
> > #5 0x94f4e52e in -[NSObject(NSKeyValueCoding) setValue:forKey:]
> > #6 0x94fd23f1 in -[NSObject(NSKeyValueCoding) setValue:forKeyPath:]
> > #7 0x93d98b1c in -[NSTreeController
> > _setMultipleValue:forKeyPath:atIndexPath:]
> > #8 0x93a2da5b in -[NSBinder
> >
> _setValue:forKeyPath:ofObject:mode:validateImmediately:raisesForNotApplicableKeys:error
> > :]
> > #9 0x93b407f9 in -[NSBinder setValue:forBinding:atIndexPath:error:]
> > #10 0x93a2d377 in -[_NSValueBinderPlugin
> > applyObjectValue:forBinding:operation:needToRunAlert:error:]
> > #11 0x93a2d1aa in -[NSValueBinder
> >
> _applyObjectValue:forBinding:canRecoverFromErrors:handleErrors:typeOfAlert:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert
> > :]
> > #12 0x93a2cea9 in -[NSValueBinder
> >
> applyDisplayedValueHandleErrors:typeOfAlert:canRecoverFromErrors:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert
> > :]
> > #13 0x93a2fbfd in -[NSValueBinder
> >
> _applyDisplayedValueIfHasUncommittedChangesWithHandleErrors:typeOfAlert:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert
> > :]
> > #14 0x93a2c78a in -[NSValueBinder
> > validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled
> > :]
> > #15 0x93a2c547 in -[_NSBindingAdaptor
> >
> _validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:bindingAdaptor
> > :]
> > #16 0x93a2c436 in -[_NSBindingAdaptor
> > validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled
> > :]
> > #17 0x93d1279b in -[NSTableView textShouldEndEditing:]
> >
> > I'm really stuck here; this is code that worked fine under Tiger. Any
> > advice on how to debug this is more than welcome.
> > TIA,
> > Doug K;
>
_______________________________________________
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