Re: KVO problems popping up in Leopard
Re: KVO problems popping up in Leopard
- Subject: Re: KVO problems popping up in Leopard
- From: David Spooner <email@hidden>
- Date: Mon, 19 Nov 2007 00:10:10 -0700
On 18-Nov-07, at 5:37 PM, Doug Knowles wrote:
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.
I had (wrongly) assumed the crash occurred in sending -
observeValueForKeyPath:... to the observer, but looking at your
original stack trace the crash occurs via -willChangeValueForKey:. I
now suspect the problem is in obtaining the old value for the change
dictionary.
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.
Do your proxy objects shadow the attributes of the model objects (say
in a dictionary), or does -valueForUndefinedKey: simply return [model
valueForKey:]? If the latter, do your proxy objects observe the
attributes of the model and invoke will/did change methods from their
observation method or are will/did invoked directly from -
setValue:forUndefinedKey:?
It might be worth considering the shadowing approach. Here your proxy
would maintain a dictionary of the relevant model properties; it would
observe those model properties and update its dictionary accordingly;
its -valueForUndefinedKey: would return a value from the dictionary;
and its -setValue:forUndefinedKey: would simply invoke the model's
setValue:forKey:. This approach avoids the need to explicitly invoke
the will/did change methods...
Thanks for the advice so far...
Doug K;
Cheers,
dave
_______________________________________________
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