Don't make me override -(void)release

  • So I've got this view that is a collection of stuff (stored in an
    NSMutableDictionary, though there is also an NSMutableArray that
    provides "order").  Some of these items support additional views that
    are inside the original collection of stuff view (e.g., an
    NSColorWell, since there are no NSColorCells).

    Normally, when the item is dealloced, it removes that view from the
    superview (i.e., -[Item dealloc] calls [myView removeFromSuperview]),
    and everything is good (I use [myCollection removeAllObjects] to
    remove everything).

    However, for some items, the view observes the underlying item (so it
    will know that something changes and needs to update - for example, an
    NSTextView whose text is bound to the item).  In this case, when I
    call [myCollection removeAllObjects], KVO logic kicks in and says
    "whoa, about to deallocate something that is still being observed,
    danger, danger, danger".  So I need to either figure out some way to
    tell KVO to not care (because the first thing dealloc for this item
    does is unbind itself from the view, so it will handle the case), or
    else I need to have a wrapper that is upstream of KVO's check (namely,
    by overriding release).

    For a document, overriding -[NSDocument close] will provide a way to
    unbind (the document), but there's no such thing here (nor is it
    practical to add an "about to remove" method, since the whole purpose
    of using an NSMutableDictionary is that it manages what is referenced
    and how).

    Unfortunately, this leaves overriding release (to see if the
    referenceCount is <= 1, and if so, do the explicit unbinding).  Since
    overriding release, an more importantly, using referenceCount for
    anything other than intellectual exercises, seem like bad things to
    do, I'm hoping there's a better pattern (especially one that could
    also work if I ever turn on gc)

    So what's a good way to unbind objects that don't have clean cut
    release patterns (since this will only be released when the last
    reference is removed, and there's no obvious case of knowing,
    especially since it may be in the dictionary more than once under
    different keys, as well as the array that keeps the order, and if
    something is "hidden" is is removed from that array)?

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    quadrium | prime : build, mutate, evolve, animate : the next
    generation of fractal art
  • --- glenn andreas <gandreas...> wrote:

    > So what's a good way to unbind objects that don't
    > have clean cut
    > release patterns (since this will only be released
    > when the last
    > reference is removed, and there's no obvious case of
    > knowing,
    > especially since it may be in the dictionary more
    > than once under
    > different keys, as well as the array that keeps the
    > order, and if
    > something is "hidden" is is removed from that
    > array)?

    It seems to me that -removeAllItems would be the best
    place for the view to remove itself as an observer
    (because that is when the view no longer cares about
    the object's changes).

    Cheers,
    Chuck

          ____________________________________________________________________________________
    Never miss a thing.  Make Yahoo your home page.
    http://www.yahoo.com/r/hs
  • On Dec 27, 2007, at 3:58 PM, Charles Steinman wrote:

    >
    > --- glenn andreas <gandreas...> wrote:
    >
    >> So what's a good way to unbind objects that don't
    >> have clean cut
    >> release patterns (since this will only be released
    >> when the last
    >> reference is removed, and there's no obvious case of
    >> knowing,
    >> especially since it may be in the dictionary more
    >> than once under
    >> different keys, as well as the array that keeps the
    >> order, and if
    >> something is "hidden" is is removed from that
    >> array)?
    >
    > It seems to me that -removeAllItems would be the best
    > place for the view to remove itself as an observer
    > (because that is when the view no longer cares about
    > the object's changes).

    The place where the view's [myCollection removeAllItems] is called
    would be just one of many possible places that the item could be
    released (since there are a bunch of routines to change/remove objects
    in the collection by name, as well as other sorts of manipulations).

    Basically, it seems error prone to have to have a parallel set of code
    to track if the item is valid or not - if it's referenced (by
    something from somewhere), it's there, if not, it's not (and will be
    released).  NSDictionary already tracks everything for it, and when
    the reference count drops to zero and the object is released (because
    it's not referenced in the dictionary any more) it goes away.  Adding
    a bunch of code to everything that modifies this dictionary to see if
    the result will be that the item is removed (and if so, call the
    item's "removeView" method) seems error prone and awkward.

    Ultimately, I'm thinking it's an error in the KVO "warning" message
    system, which shouldn't kick in until the object is actually freed
    (i.e., when NSObject's dealloc calls NSDeallocateObject), as opposed
    to before the first line of derived dealloc routine (which prevents
    the object from being able to unbind anything it owns).

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    quadrium | prime : build, mutate, evolve, animate : the next
    generation of fractal art
previous month december 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
31            
Go to today