I will try to explain the value of delegation with one example.
Say you have a table; the table will show some rows. Suppose now, you want to customize the way this table react to some event, e.g., the selection of a specific row.
One common way of doing this in OOP is subclassing a table base class and overriding some methods there.
With delegation, you don't need subclassing the table base class; rather you use the base class and tell it to "forward" some messages to some other object. This is the basic idea.
In our example, when the row is clicked, the table base class does not know what do except sending a message to one object that you specify as the delegate to carry through that action.
So, one basic advantage of delegation is that you do not need to subclass. Another advantage you have is that a delegate can act as the delegate for several other objects. Indeed, if you have a look at the generic declaration of a delegate method, you will see that the first parameter is the object that is delegating:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
so when the delegate receives the message, it knows who sent it and with which object it should interact.
The example I gave you about the table shows one kind of delegation, which I would not compare to callbacks. Anyway, delegation can be used as well as a kind of advanced calling-back-scheme.
Take the class NSURLConnection
; it can be used to manage aynchronous communication.
Async communication is the typical case where callbacks are used.
With NSURLConnection
, the delegate pattern is preferred; so, instead of specifying a callback (a function, which has to be a static function, or a static class method), you specify an object. This object implements the methods that a protocol defines (NSURLConnectionDelegate
protocol); you can see those as a whole set of callback functions. When the NSURLConnection
has some data ready, it will call a method of the interface, e.g., – connection:didReceiveResponse:
to notify that it has received the response.
In such case, the point is not avoiding subclassing, rather it is a more flexible callback mechanisms (allowing for better encapsulation, basically).
I hope this helps clarifying the two concepts...