[worker setDelegate:self];
And because of the nature of Objective-C, the worker can simply invoke any of it's delegate methods as needed:
if([delegate respondsToSelector:@selector(workerDidFinish:)] )
{
[delegate workerDidFinish:self];
}
Things are a bit different in C#. The client registers for every event it's interested in:
worker.DidStart += new Worker.DidStart(wStart);
worker.DidFinish += new Worker.DidFinish(wFinish);
And the worker invokes the delegate methods like so:
if(DidFinish != null)
{
DidFinish(this);
}
When there are a bunch of events, it's sometimes annoying to have to register for all of them. It's equally annoying when one has to unregister for all of them individually, as opposed to a simple "setDelegate:nil" operation. However, the C# delegate/event system has one very interesting property. Multiple clients can all register for the same event, and the code above would invoke all delegate methods, no changes needed.
This is similar to the NSNotification stuff in Cocoa. However, the multicast delegate system makes it a LOT easier when you have a bunch of "notifications", and your "notifications" have multiple parameters.
And when would you need to have multiple delegates? I can think of several examples, but here's one that's closer to home for me:
Say you're writing a hypothetical xmpp framework for cocoa developers. When a message is received, the framework doesn't exactly know who needs to hear about it. Maybe a chat window. Maybe a history logging class. Maybe the roster. Maybe all of the above. I suppose one could write a big giant engine that plows through all possible message types, and forwards them to the appropriate sources. But this isn't exactly the most scalable and extensive solution. This is where multicast delegates could come in handy.
And thus, I wrote a MulticastDelegate class. It works like so:
// Multiple clients can all do this
[worker addDelegate:self];
And the worker code looks like this:
// In init method or wherever
multicastDelegate = [[MulticastDelegate alloc] init];
- (void)addDelegate:(id)delegate {
[multicastDelegate addDelegate:delegate];
}
- (void)removeDelegate:(id)delegate {
[multicastDelegate removeDelegate:delegate];
}
// And whenever the worker is finished
[multicastDelegate workerDidFinish:self];
And that's all there is to it. The multicast delegate class manages the list of delegates, and automatically forwards any message you send it to all the delegates (if they respond to the message of course).
2 comments:
I think you really are looking for NSNotifications -- which help to implement the observer pattern that you describe.
Did you not read the article? He pointed out that notifications are difficult to use IF you have multiple parameters to pass. How do you pass several different parameters in a notification? You have to pack the parameters into a NSDictionary object. And then, on top of that, the receivers of the notification have to unpack the objects from the dictionary. And in order to do this, they have to know the proper keys to use. Now imagine that your class has dozens of events, each with multiple parameters, and several delegates per event. Do you really want to use notifications for this? Hence - the creation of multicast delegates. They're not a total replacement for notifications. They just make life easier in a particular situation.
Post a Comment