Re: notifications vs delegates (was: The fuzzy aspects of Cocoa)
Re: notifications vs delegates (was: The fuzzy aspects of Cocoa)
- Subject: Re: notifications vs delegates (was: The fuzzy aspects of Cocoa)
- From: Jay Kuri <email@hidden>
- Date: Wed, 27 Feb 2002 00:24:25 -0600
Absolutely great. Thank you so much. This was exactly what I needed to
know.
FYI - I'm going to use the notification model. It is very possible that
an app might want to have several objects react to recieved messages.
Thanks again!
Jay
On Tuesday, February 26, 2002, at 09:42 PM, email@hidden wrote:
I read this and another at cocoadevcentral and I have a question.
The stepwise article implies that notifications are slower than a
delegates... (relating to looking up in a hash table vs just using the
selector) my question here is: how much slower are they? does it
really make enough of a difference to choose one over the other in
'normal' situations?
No. Typically, you should choose the solution that better fits your
situation. The speed of notifications will only be a problem if you're
delivering hundreds of them (at least -- probably more like thousands)
per second. Assuming the method hit by the notification is quick, of
course.
The one thing I didn't notice is when to use one over the other if you
are not looking for possible veto (close window example). Suppose you
have an object (part of a framework) that wants to deliver a small
chunk
of data to an interested object. Normally, this data would only be of
interest to a single object... is there a reason to choose delegates
over notifications or vice versa?
OK, I'll take a crack at this.
One big distinction is that delegates are to-one. One object
creating data of interest, one delegate for that object that is given
the data. Notifications are at least potentially to-many: for each
object creating data of interest, there can be many objects being given
that data. Even if only one other object is in fact going to listen
for the data in your current design, the "feel" of this is important to
deciding which model to use. Would it be reasonable for some other
object to want to listen as well? Is this data potentially of general
interest? Or is it really intended for, and of interest to, only one
object regardless of the implementation details you end up with?
Typically, the reason that one only object legitimately has an
interest in data generated by another object is that one object is "in
charge" of another object. NSTextView illustrates this well. Ignoring
things defined in its superclass NSText, it has only two notifications:
one when its selection changes, and another that is a little complex
but irrelevant to this discussion. It is easy to see how the selection
changing would be of general interest: one can imagine controls
enabling and disabling based upon the selection, other widgets
reflecting the selected text, inspectors showing information, toolbar
buttons changing state, etc. Each of these side effects of the
selection changing could be considered to be independant; there is not
necessarily any conceptual need for a single object that "coordinates"
all this.
On the other hand, NSTextView has a bunch of delegate methods that
were not made into notifications, because they really only make sense
to a single delegate object that is "in charge" of the textview.
Examples of these messages are cells being clicked on or dragged, links
being clicked, and messages that ask for "permission" or clarification
on actions the textview plans to take. You probably would never want
two completely independant actions to occur because a link in a
textview was clicked; somebody is "in charge" of that link, and will
handle whatever consequences need to occur when it is clicked.
Another good example of this distinction is the target-action
mechanism. When a button is pressed, it is really only appropriate for
a single method on a single object to be called. This may cause a
cascade of messages to a whole bunch of objects, but there really ought
to be a single object initiating the process, because that single
object is "in charge" of that button. Target-action can be thought of,
sort of, as a delegate relationship. For the convenience of the
programmer, the action called on the "delegate" is flexible, but the
essence is the same, I think.
Another big distinction is the "looseness" of the coupling. An
object with a delegate must have an explicit (and probably retained)
reference to its delegate. It calls the appropriate method directly on
its delegate. Whether this reference is appropriate or not should
strongly drive your decision regarding whether to use delegation or
notifications.
For example, it is entirely appropriate for an application to have a
direct reference to its delegate. App delegates are typically
singleton objects created for the sole purpose of "advising" and
"controlling" the application object and handling top-level application
concerns. Decoupling that relationship would be unnecessary in most
cases. (Most of NSApp's messages are of potentially general interest,
however, so they are *also* provided as notifications in most cases).
On the other hand, when your preferences panel is run and some pref
is changed, it is probably inappropriate for your preferences object to
have a direct reference to the object in your app that is governed by
that pref. That would be exposing implementation details between parts
of your app that probably can and should be modular and separate. So
posting a notification in this case often makes more sense.
The final big distinction (that I can think of right now) is that
delegates can return values, notification targets can't (or not
easily). Returning a vlue to the sender usually implies a "control"
relationship -- the delegate is affecting the object's behaviour
somehow, so it can be said to be "in charge" of that object. If you
need to return a value to the sender, that strongly implies that you
want a delegate. The one exception would be in you are conceptually
"taking a poll" or "collecting results" from however many objects
happen to respond, in which case notifications can be appropriate.
From what I gather, notifications are a bit more flexible in terms of
dynamic messages (notifications with names that are defined at run
time)
but delegates are faster...
The speed difference is irrelevant to most situations; you would do
well to (mostly) forget about it, it should generally not influence you.
Notifications are more general, yes. They can go to more than one
destination, the sender doesn't need to keep references to the
receivers, etc. However, they are also more dangerous. This danger is
usually much more relevant to apps than the speed problem.
They are dangerous because it is easy for them to get out of
control. You can easily end up with an app where notification A is
listened to by a half-dozen objects, many of which send their own
notifications in response, and so on -- a single notification turns
into a cascade of mostly pointless and repetitious method calls. It is
hard to believe how insidious this can be until it happens to your own
app. :-> The delegate, being to-one in nature, tends to side-step
this problem.
In summary, don't just use notifications because they're more
general, and don't just use delegates because they're cleaner, easier
to understand, or faster. Use whichever one is really appropriate
given the object design of your app, keeping in mind the principles
elucidated above.
Well, that was a lot of typing. I hope it was useful. :->
Ben Haller
Stick Software
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.