FROM : David Spooner
DATE : Mon Nov 19 08:10:10 2007
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
DATE : Mon Nov 19 08:10:10 2007
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
| Related mails | Author | Date |
|---|---|---|
| Doug Knowles | Nov 15, 04:01 | |
| David Spooner | Nov 15, 08:19 | |
| Doug Knowles | Nov 19, 01:37 | |
| David Spooner | Nov 19, 08:10 | |
| Doug Knowles | Nov 19, 14:12 |






Cocoa mail archive

