Understanding Delegation

I’ve seen a lot of people learning iOS for the first time. Some of them have been learning Objective-C as their first programming language. Understanding delegation is without fail a stumbling block as you learn the language and the frameworks. This blog post is going to attempt to explain delegation using what I have come up with as my best analogy for it so far. I call this analogy “the Shirt Delegate.”

While not many people can relate directly to the fantastically rich, we can imagine the things we would want in our life if, say, Google bought our app for a cool billion. You might want fancy cars or a new Mac Pro, but you know what I want? A Shirt Delegate.

When fantastically-rich Jeff goes to bed at night, I take off my shirt and put it in a bin. When I wake up, the shirt is gone and a new one is hanging in my closet, pressed and ready to wear. I don’t know how it got there, and I don’t care. All I know is this:

  • When I took my shirt off, I handed it to my delegate (in this case, using the bin in my closet)
  • In the morning, when I needed a shirt, it was provided by the delegate

I don’t need to know my shirt delegate’s name, or really even anything about him or her. Heck, I don’t even need to know if my shirt delegate is human. All I care about as far as he or she is concerned is the shirt situation.

Delegates, you see, are a lot like this. A given delegate is there to respond to its master’s whims. Consider a table view delegate. It knows someone tapped on a cell, so it calls its delegate’s ‑tableView:didSelectRowAtIndexPath: method—and that’s the extent of what it knows about what the delegate is going to do with that information.

Our shirt delegate, then, might have two methods:

@protocol ShirtDelegate

– (void)personDidRemoveShirt:(Shirt *)aShirt;
– (Shirt *)shirtForToday;

@end

Only the important information is included in each.

Consider the application delegate. The application starts up, and let’s say it has a push notification the user tapped to invoke it, so it has something in the launchOptions dictionary. The application reads the value passed in to UIApplicationMain() in the main.m file to find out the kind of delegate it needs, creates one, and hands over the launchOptions dictionary to it. In this case the application does know a little bit about the delegate—enough to create one, anyway. But it doesn’t need to know anything about the launchOptions dictionary or anything about what happens in ‑application:didFinishLaunchingWithOptions:.

The purpose of delegation is simple: to decouple your code. The more knowledge a class has about other classes, the more coupling there is in your code. Like a spiderweb sticking to everything, this coupling makes it harder to change individual portions of your app, harder to migrate your apps to new platforms, and is just generally messy. Bringing it back to our original analogy: the fantastically rich are too busy worried about their fleet of supercars, their investment portfolio, and the design of the foyer in their third home; they don’t care about what brand of detergent the shirt delegate uses.