Skip navigation.
 
mlRe: KVO problems popping up in Leopard
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

Related mailsAuthorDate
mlKVO problems popping up in Leopard Doug Knowles Nov 15, 04:01
mlRe: KVO problems popping up in Leopard David Spooner Nov 15, 08:19
mlRe: KVO problems popping up in Leopard Doug Knowles Nov 19, 01:37
mlRe: KVO problems popping up in Leopard David Spooner Nov 19, 08:10
mlRe: KVO problems popping up in Leopard Doug Knowles Nov 19, 14:12