Re: Right place to unobserve notifications in a document
Re: Right place to unobserve notifications in a document
- Subject: Re: Right place to unobserve notifications in a document
- From: Negm-Awad Amin <email@hidden>
- Date: Tue, 19 Aug 2008 08:05:33 +0200
Am Mo,18.08.2008 um 20:14 schrieb Andy Lee:
On Aug 18, 2008, at 12:49 PM, Negm-Awad Amin wrote:
Am Mo,18.08.2008 um 18:18 schrieb Andy Lee:
-- but in this case I think -dealloc is not only okay, but
sometimes the only correct place to unregister a notification.
Suppose an invariant of your design is that an object should
receive notifications as long as, and only as long as, the object
exists. If you unregister too soon, you may have an "alive"
object that fails to get a notification.
This is little bit a circular argumentation: I need it the whole
lifetime, so i manage it the whole lifetime. Why do you need it
until the instance becomes deconstructed?
It's only circular in that I specifically selected a class of
situations where it makes the most sense. :)
I think this is the right pattern:
1. Construct and init the object
2. Let them work (register observations, handling threads,
$whatever … )
3. Stop them
4. Deconstruct them
So there are 4 steps, not 2.
This pattern is fine and necessary in many cases, but there are also
plenty of cases where it is not viable. For example, it may not be
clear when the object can "stop" listening for notifications. It
may literally be when all other objects are done with it, i.e., when
its retain count goes to zero, and in a dynamic system you may have
no way of knowing which will be the last object to release your
object.
IMO imposing a start-stop paradigm on every class that wants to
register interest in notifications -- and engineering every class so
that your object can't possibly be released until it is "stopped" --
is just as much a design error as putting functional work in -
dealloc. I would encourage you to reconsider.
As I said, in the past I used this pattern very often. And indeed the
reason was, that if somebody A is retaining somebody B, A uses B. So I
can mix up functional work and memory management. This seems to be
convient.
If you put it together, you have no possibility of stopping somebody
without releasing it. And since you can not be sure, that somebody
else holds it, you have to reinstantiate B for a new start. I think in
practice a "2-step-pattern" makes sharing of the functionality harder!
In the cases where you do have a start-stop paradigm, you should put
a "stop" in -dealloc anyway, as Michael argued.
You should throw an exception or at least log something, as oberserved
objects actually do ("dealloc while observation in place" or something
like this).
I think it's okay to unregister in -dealloc because conceptually
it's related to releasing your ivars. You're explicitly
dissolving a relationship between the object being dealloced and
some other object -- a relationship you have to manually manage in
the absence of garbage collection.
In this case it seems to be ok. Maybe this is the reason for the
weak reference.
The weak reference is to avoid retain cycles (the same reason why
delegates are not retained).
We talked about GC. The need for a weak reference using RC is quite
clear.
With GC turned on, retain cycles are not a problem so you don't have
to worry about weak references to self, just as you don't have to
bother releasing strong references to ivars.
Since the observed object (maybe notification center) will still hold
a reference to the observing object, there is a problem. The
*observer* will not be freed, if the observed is still living.
Obviously you have a problem using GC, for example if you have an
observing window and an observed model instance. The model probably
lives longer than the window. (Think of info windows …)
This seems to be the reason for the weak reference using GC.
In the absence of GC, you have to break connections manually, and
that's all this is. In fact, you should also break delegate
connections to self in the same place, for the same reason. (Hm,
I'm not sure whether I'm doing this in my own code -- I'd better
check.)
You mentioned KVO in another reply. I haven't used KVO, so I'd be
interested if anyone has a response to your counterexample.
Still waiting … ;--)
Cheers,
Amin
--Andy
Amin Negm-Awad
email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden