Avoiding KVO in dealloc?

  • While working through "Beginning iPhone 3 Development" I've seen the
    following a lot, and it seems like a general Cocoa issue.

    In -viewDidUnload methods the code has the form:
    self.foo = nil;

    Whereas in -dealloc methods the code has the form:
    [foo release];

    Both methods seem to me to do the same thing (releasing foo), but I
    presume the first one would trigger any KVO observers where as the
    second wouldn't. Is that why the simple "release" is used instead of a
    setter in the dealloc methods, to avoid KVO? Is this a general Cocoa
    pattern?

    Thanks,

    Todd
  • On Mon, Aug 3, 2009 at 4:35 PM, Todd Heberlein<todd_heberlein...> wrote:
    > Both methods seem to me to do the same thing (releasing foo), but I presume
    > the first one would trigger any KVO observers where as the second wouldn't.
    > Is that why the simple "release" is used instead of a setter in the dealloc
    > methods, to avoid KVO? Is this a general Cocoa pattern?

    Yes, it's a general pattern.  Not just to avoid KVO, but any custom
    accessor/mutator behavior.

    The rule of thumb is never use your accessors/mutators inside -init or
    -dealloc, and always use them elsewhere.

    --Kyle Sluder
  • On 04/08/2009, at 9:46 AM, Kyle Sluder wrote:

    > On Mon, Aug 3, 2009 at 4:35 PM, Todd
    > Heberlein<todd_heberlein...> wrote:
    >> Both methods seem to me to do the same thing (releasing foo), but I
    >> presume
    >> the first one would trigger any KVO observers where as the second
    >> wouldn't.
    >> Is that why the simple "release" is used instead of a setter in the
    >> dealloc
    >> methods, to avoid KVO? Is this a general Cocoa pattern?
    >
    > Yes, it's a general pattern.  Not just to avoid KVO, but any custom
    > accessor/mutator behavior.
    >
    > The rule of thumb is never use your accessors/mutators inside -init or
    > -dealloc, and always use them elsewhere.

    Unless, of course, you have code in your setter method that handles
    changes to and from nil. For example, you may add or remove self as an
    observer for keypaths of an different object value. This would save
    repeating the change handling code in your init, setter and dealloc
    methods.

    Kiel
  • On Aug 3, 2009, at 5:03 PM, Kiel Gillard <kiel.gillard...> wrote:
    > Unless, of course, you have code in your setter method that handles
    > changes to and from nil. For example, you may add or remove self as
    > an observer for keypaths of an different object value. This would
    > save repeating the change handling code in your init, setter and
    > dealloc methods.

    No, this is precisely what you should not do. -init and -dealloc
    should not invoke accessor methods, because the object is in a
    partially constructed state that subclasses (including the dynamically
    created ones KVO makes) often can't handle.

    --Kyle Sluder
  • On 04/08/2009, at 10:26 AM, Kyle Sluder wrote:

    > On Aug 3, 2009, at 5:03 PM, Kiel Gillard <kiel.gillard...>
    > wrote:
    >> Unless, of course, you have code in your setter method that handles
    >> changes to and from nil. For example, you may add or remove self as
    >> an observer for keypaths of an different object value. This would
    >> save repeating the change handling code in your init, setter and
    >> dealloc methods.
    >
    > No, this is precisely what you should not do. -init and -dealloc
    > should not invoke accessor methods, because the object is in a
    > partially constructed state that subclasses (including the
    > dynamically created ones KVO makes) often can't handle.

    Do you have a documentation reference for that? I would have expected
    the isa swizzling to be an implementation detail of the runtime that
    is handled before my subclass inits. Of course, what I expect and what
    happens in reality do not always match ;-)

    Kiel
  • On Mon, Aug 3, 2009 at 5:47 PM, Kiel Gillard<kiel.gillard...> wrote:
    > Do you have a documentation reference for that? I would have expected the
    > isa swizzling to be an implementation detail of the runtime that is handled
    > before my subclass inits. Of course, what I expect and what happens in
    > reality do not always match ;-)

    The Objective-C 2.0 Programming Guide prescribes the use of direct
    ivar access inside an initializer[1] and inside dealloc[2].

    As far as your point about when swizzling occurs, it can only happen
    at the point of a KVO observer registration: the runtime can't predict
    the future.

    --Kyle Sluder

    [1] http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articl
    es/ocAllocInit.html#//apple_ref/doc/uid/TP30001163-CH22-SW14

    [2] http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articl
    es/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW16
  • On 04/08/2009, at 10:59 AM, Kyle Sluder wrote:

    > On Mon, Aug 3, 2009 at 5:47 PM, Kiel Gillard<kiel.gillard...>
    > wrote:
    >> Do you have a documentation reference for that? I would have
    >> expected the
    >> isa swizzling to be an implementation detail of the runtime that is
    >> handled
    >> before my subclass inits. Of course, what I expect and what happens
    >> in
    >> reality do not always match ;-)
    >
    > The Objective-C 2.0 Programming Guide prescribes the use of direct
    > ivar access inside an initializer[1] and inside dealloc[2].
    >
    > [1] http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articl
    es/ocAllocInit.html#/

    > /apple_ref/doc/uid/TP30001163-CH22-SW14
    > [2] http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articl
    es/ocProperties.html#/

    > /apple_ref/doc/uid/TP30001163-CH17-SW16

    Thanks for these - much appreciated. The -dealloc commentary was very
    helpful. For the OP, this means care should be taken to unobserve key
    paths before dealloc. One way this could be done by observing
    NSApplicationWillTerminateNotification.

    The constraints and conventions commentary for the init method seems
    to be more about coding style (consistency in style during
    initialisation and deallocation) as one could argue the side affects
    of a custom accessor are desired (such as registering a new object
    value of an instance variable for KVO notifications).

    > As far as your point about when swizzling occurs, it can only happen
    > at the point of a KVO observer registration: the runtime can't predict
    > the future.

    When if I observe some property of Foo *bar at some point in time, KVO
    swizzles the isa to KVONotifying_Foo. Then, if I observe a different
    property of the same object at some other point in time, are you
    suggesting KVO swizzles the isa to KVONotifying_Foo2 which in turn
    "can often" break future KVO notifications?

    Kiel
  • On Mon, Aug 3, 2009 at 6:32 PM, Kiel Gillard<kiel.gillard...> wrote:
    > When if I observe some property of Foo *bar at some point in time, KVO
    > swizzles the isa to KVONotifying_Foo. Then, if I observe a different
    > property of the same object at some other point in time, are you suggesting
    > KVO swizzles the isa to KVONotifying_Foo2 which in turn "can often" break
    > future KVO notifications?

    No, I wasn't trying to imply anything about the actual behavior of
    KVO-generated subclasses.  I was referring to the fact that it doesn't
    know about your implementation, and if you use accessors in your
    -dealloc you might run afoul of the expected behavior of any subclass,
    including those generated by KVO.

    --Kyle Sluder
  • On Aug 3, 2009, at 6:32 PM, Kiel Gillard wrote:
    > On 04/08/2009, at 10:59 AM, Kyle Sluder wrote:
    > On Mon, Aug 3, 2009 at 5:47 PM, Kiel Gillard<kiel.gillard...>
    > wrote:
    >>> Do you have a documentation reference for that? I would have
    >>> expected the
    >>> isa swizzling to be an implementation detail of the runtime that
    >>> is handled
    >>> before my subclass inits. Of course, what I expect and what
    >>> happens in
    >>> reality do not always match ;-)
    >>
    >> The Objective-C 2.0 Programming Guide prescribes the use of direct
    >> ivar access inside an initializer[1] and inside dealloc[2].
    >>
    >> [1] http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articl
    es/ocAllocInit.html#/

    >> /apple_ref/doc/uid/TP30001163-CH22-SW14
    >> [2] http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articl
    es/ocProperties.html#/

    >> /apple_ref/doc/uid/TP30001163-CH17-SW16
    >
    > Thanks for these - much appreciated. The -dealloc commentary was
    > very helpful. For the OP, this means care should be taken to
    > unobserve key paths before dealloc. One way this could be done by
    > observing NSApplicationWillTerminateNotification.

    Assuming the objects you were observing lasted as long as the app,
    yes. For anything shorter term (e.g. document data), you still need to
    know when the object will be dealloced and stop observing before then.

    Dave
previous month august 2009 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
31            
Go to today