Re: KVO problems popping up in Leopard - KVO notifying a released object I never owned

  • Sigh. NSZombieEnabled works much better when set to "YES" instead of "1"...
    It would appear that KVO is trying to send a change notification to a
    released observer that was removed as an observer of my proxy object.  Log
    output below.

    The only binding to this property is from an outline view's table column
    which uses the default NSTextFieldCell; the error occurs when I edit the
    object's value and commit the change.

    For those who have been following the thread, the property in question is
    now implemented with a getter/setter and is no longer processed through the
    ...forUndefinedKey methods.  I am also restricting myself to the use of
    valueForKey: and setValue:forKey to manipulate this property.

    I always hesitate to assume the problem is not in my code, but this really
    feels like a problem with some fairly basic NSOutlineView behavior.  I'd be
    happy to be proven wrong if it leads to a fix.

    TIA,
    Doug K;

    *2007-11-20 08:02:23.894 SLNavigator[2868:813] *** -[NSKeyValueObservance
    retain]: message sent to deallocated instance 0xcecf930*

    Program received signal:  "SIGTRAP".

    Prior log references to this object:

    *2007-11-20 08:02:12.363 SLNavigator[2868:813] @@@ LVProxyCategory 0xcebd780
    adding observer (<NSKeyValueObservance 0xcecf930: Observer: 0xceb6720, Key
    path: representedObject.lvName, Options: <New: NO, Old: NO, Prior: NO>
    Context: 0xa06c128c, Property: 0xcecf8c0>) for key path: lvName*

    *2007-11-20 08:02:20.124 SLNavigator[2868:813] @@@ LVProxyLinkedItem
    0xe136f00 adding observer (<NSKeyValueObservance 0xcecf930: Observer:
    0xceb6720, Key path: representedObject.lvName, Options: <New: NO, Old: NO,
    Prior: NO> Context: 0xa06c128c, Property: 0xcecf8c0>) for key path: lvName*

    *2007-11-20 08:02:20.135 SLNavigator[2868:813] @@@ LVProxyCategory 0xcebd780
    removing observer (<NSKeyValueObservance 0xcecf930: Observer: 0xceb6720, Key
    path: representedObject.lvName, Options: <New: NO, Old: NO, Prior: NO>
    Context: 0xa06c128c, Property: 0xcecf8c0>) for key path: lvName*

    *2007-11-20 08:02:20.138 SLNavigator[2868:813] @@@ LVProxyLinkedItem
    0xe136f00 removing observer (<NSKeyValueObservance 0xcecf930: Observer:
    0xceb6720, Key path: representedObject.lvName, Options: <New: NO, Old: NO,
    Prior: NO> Context: 0xa06c128c, Property: 0xcecf8c0>) for key path: lvName*

    Stack trace at the time of the trap:

    #0 0x91361a27 in ___forwarding___
    #1 0x91361b32 in __forwarding_prep_0___
    #2 0x91fec880 in NSKVOPendingNotificationCreate
    #3 0x91f6958d in -[NSObject(NSKeyValueObserverNotification)
    willChangeValueForKey:]
    #4 0x000311fa in -[ListViewItemProxy willChangeValueForKey:] at
    ListViewItemProxy.m:501
    #5 0x91fec2ed in _NSSetObjectValueAndNotify
    #6 0x91f8e52e in -[NSObject(NSKeyValueCoding) setValue:forKey:]
    #7 0x920123f1 in -[NSObject(NSKeyValueCoding) setValue:forKeyPath:]
    #8 0x94c16b1c in -[NSTreeController
    _setMultipleValue:forKeyPath:atIndexPath:]
    #9 0x948aba5b in -[NSBinder
    _setValue:forKeyPath:ofObject:mode:validateImmediately:raisesForNotApplicableKeys:error:]
    #10 0x949be7f9 in -[NSBinder setValue:forBinding:atIndexPath:error:]
    #11 0x948ab377 in -[_NSValueBinderPlugin
    applyObjectValue:forBinding:operation:needToRunAlert:error:]
    #12 0x948ab1aa in -[NSValueBinder
    _applyObjectValue:forBinding:canRecoverFromErrors:handleErrors:typeOfAlert:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert:]
    #13 0x948aaea9 in -[NSValueBinder
    applyDisplayedValueHandleErrors:typeOfAlert:canRecoverFromErrors:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert:]
    #14 0x948adbfd in -[NSValueBinder
    _applyDisplayedValueIfHasUncommittedChangesWithHandleErrors:typeOfAlert:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert:]
    #15 0x948aa78a in -[NSValueBinder
    validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:]
    #16 0x948aa547 in -[_NSBindingAdaptor
    _validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:bindingAdaptor:]
    #17 0x948aa436 in -[_NSBindingAdaptor
    validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:]
    #18 0x94b9079b in -[NSTableView textShouldEndEditing:]

    On Nov 19, 2007 8:12 AM, Doug Knowles <knowles.doug...> wrote:

    >
    >
    > On Nov 19, 2007 2:10 AM, David Spooner <dave...> wrote:
    >
    >> 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:?
    >>
    >
    > I've been invoking the will/did change methods from the observe... method
    > for the model object keys.
    >
    >>
    >> 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...
    >>
    >
    > For the property in question, I implemented getter/setter methods in the
    > proxy since I started encountering this problem; these methods provided no
    > backing store for the property, so I've been returning NO from +
    > accessInstanceVariablesDirectly.  Your suggestion to maintain a dictionary
    > is a more general solution for the other (dynamically generated properties)
    > my proxy; I'll try that today.
    >
    > Thanks again for your time and assistance!
    >
  • Please disregard.  My override of removeObserver... sometimes doesn't
    invoker super. Mea culpa, mea maxima culpa.
    I still have problems to fix, but they're all mine and I can see them now.

    Thanks again, David, for your time and attention; your mention of zombies
    caused me to re-check the args and find that mistake.

    On Nov 20, 2007 8:44 AM, Doug Knowles <knowles.doug...> wrote:

    > Sigh. NSZombieEnabled works much better when set to "YES" instead of
    > "1"...
    > It would appear that KVO is trying to send a change notification to a
    > released observer that was removed as an observer of my proxy object.  Log
    > output below.
    >
    > The only binding to this property is from an outline view's table column
    > which uses the default NSTextFieldCell; the error occurs when I edit the
    > object's value and commit the change.
    >
    > For those who have been following the thread, the property in question is
    > now implemented with a getter/setter and is no longer processed through the
    > ...forUndefinedKey methods.  I am also restricting myself to the use of
    > valueForKey: and setValue:forKey to manipulate this property.
    >
    > I always hesitate to assume the problem is not in my code, but this really
    > feels like a problem with some fairly basic NSOutlineView behavior.  I'd be
    > happy to be proven wrong if it leads to a fix.
    >
    > TIA,
    > Doug K;
    >
    > *2007-11-20 08:02: 23.894 SLNavigator[2868:813] *** -[NSKeyValueObservance
    > retain]: message sent to deallocated instance 0xcecf930*
    >
    > Program received signal:  "SIGTRAP".
    >
    > Prior log references to this object:
    >
    > * 2007-11-20 08:02:12.363 SLNavigator[2868:813] @@@ LVProxyCategory
    > 0xcebd780 adding observer (<NSKeyValueObservance 0xcecf930: Observer:
    > 0xceb6720, Key path: representedObject.lvName, Options: <New: NO, Old: NO,
    > Prior: NO> Context: 0xa06c128c, Property: 0xcecf8c0>) for key path: lvName
    > *
    >
    > *2007-11-20 08:02:20.124 SLNavigator[2868:813] @@@ LVProxyLinkedItem
    > 0xe136f00 adding observer (<NSKeyValueObservance 0xcecf930: Observer:
    > 0xceb6720, Key path: representedObject.lvName, Options: <New: NO, Old: NO,
    > Prior: NO> Context: 0xa06c128c, Property: 0xcecf8c0>) for key path: lvName
    > *
    >
    > *2007-11-20 08:02:20.135 SLNavigator[2868:813] @@@ LVProxyCategory
    > 0xcebd780 removing observer (<NSKeyValueObservance 0xcecf930: Observer:
    > 0xceb6720, Key path: representedObject.lvName, Options: <New: NO, Old: NO,
    > Prior: NO> Context: 0xa06c128c, Property: 0xcecf8c0>) for key path: lvName
    > *
    >
    > *2007-11-20 08:02:20.138 SLNavigator[2868:813] @@@ LVProxyLinkedItem
    > 0xe136f00 removing observer (<NSKeyValueObservance 0xcecf930: Observer:
    > 0xceb6720, Key path: representedObject.lvName, Options: <New: NO, Old: NO,
    > Prior: NO> Context: 0xa06c128c, Property: 0xcecf8c0>) for key path: lvName
    > *
    >
    >
    > Stack trace at the time of the trap:
    >
    > #0 0x91361a27 in ___forwarding___
    > #1 0x91361b32 in __forwarding_prep_0___
    > #2 0x91fec880 in NSKVOPendingNotificationCreate
    > #3 0x91f6958d in -[NSObject(NSKeyValueObserverNotification)
    > willChangeValueForKey:]
    > #4 0x000311fa in -[ListViewItemProxy willChangeValueForKey:] at
    > ListViewItemProxy.m:501
    > #5 0x91fec2ed in _NSSetObjectValueAndNotify
    > #6 0x91f8e52e in -[NSObject(NSKeyValueCoding) setValue:forKey:]
    > #7 0x920123f1 in -[NSObject(NSKeyValueCoding) setValue:forKeyPath:]
    > #8 0x94c16b1c in -[NSTreeController
    > _setMultipleValue:forKeyPath:atIndexPath:]
    > #9 0x948aba5b in -[NSBinder
    > _setValue:forKeyPath:ofObject:mode:validateImmediately:raisesForNotApplicableKeys:error:]
    > #10 0x949be7f9 in -[NSBinder setValue:forBinding:atIndexPath:error:]
    > #11 0x948ab377 in -[_NSValueBinderPlugin
    > applyObjectValue:forBinding:operation:needToRunAlert:error:]
    > #12 0x948ab1aa in -[NSValueBinder
    > _applyObjectValue:forBinding:canRecoverFromErrors:handleErrors:typeOfAlert:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert:]
    >
    > #13 0x948aaea9 in -[NSValueBinder
    > applyDisplayedValueHandleErrors:typeOfAlert:canRecoverFromErrors:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert:]
    >
    > #14 0x948adbfd in -[NSValueBinder
    > _applyDisplayedValueIfHasUncommittedChangesWithHandleErrors:typeOfAlert:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert:]
    >
    > #15 0x948aa78a in -[NSValueBinder
    > validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:]
    > #16 0x948aa547 in -[_NSBindingAdaptor
    > _validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:bindingAdaptor:]
    > #17 0x948aa436 in -[_NSBindingAdaptor
    > validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:]
    > #18 0x94b9079b in -[NSTableView textShouldEndEditing:]
    >
    >
    >
    > On Nov 19, 2007 8:12 AM, Doug Knowles <knowles.doug...> wrote:
    >
    >>
    >>
    >> On Nov 19, 2007 2:10 AM, David Spooner <dave...> wrote:
    >>
    >>> 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:?
    >>>
    >>
    >> I've been invoking the will/did change methods from the observe...
    >> method for the model object keys.
    >>
    >>>
    >>> 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...
    >>>
    >>
    >> For the property in question, I implemented getter/setter methods in the
    >> proxy since I started encountering this problem; these methods provided no
    >> backing store for the property, so I've been returning NO from +
    >> accessInstanceVariablesDirectly.  Your suggestion to maintain a
    >> dictionary is a more general solution for the other (dynamically generated
    >> properties) my proxy; I'll try that today.
    >>
    >> Thanks again for your time and assistance!
    >>
    >
    >
previous month november 2007 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today