Tutorial: delegates and delegation in Objective-C

[Download Xcode 9 project with full Objective-C source from GitHub.]

Introduction

I’m going to talk about “delegates” and “delegation.” I’ll lead you through a simple example of implementing the delegation design pattern in Objective-C, with full source code, and then show you a more sophisticated scenario. My intent here is to show you how delegation works without getting bogged down in some crazy complex example. Download the Xcode 9 project with full Objective-C source from GitHub to follow along.

I’ll show you how to build a user interface (UI) component, a status/progress indicator, which you can display on screen for processing-intensive tasks… AND I’ll show you how you can customize the behavior of the indicator by using delegation. For example, when the indicator starts, you could disable your UI; when the indicator stops, you could re-enable your UI; and, when the user taps the indicator, you could cancel processing-intensive tasks. Here’s the app we’ll build:


Recommended reading
In order to help you in understanding how I build my sample delegation code herein, you should read my articles on “Using Swift extensions to manage complexity, improve readability, and increase extensibility (UICollectionView, protocols, and delegates)” and “Understanding Swift 4 protocols and using them in your apps.”

Delegation
Let’s start with a layman’s definition of some terms.

The dictionary definition of “delegate” (Cambridge) is “to give a particular job, duty, right, etc. to someone else so that they do it for you.” The dictionary definition of “delegation” (Merriam-Webster) is “the act of empowering to act for another.”

According to Apple:

Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object–the delegate–and at the appropriate time sends a message to it. The message informs the delegate of an event that the delegating object is about to handle or has just handled. The delegate may respond to the message by updating the appearance or state of itself or other objects in the application, and in some cases it can return a value that affects how an impending event is handled. The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object. …

and also:

A delegate is an object that acts on behalf of, or in coordination with, another object when that object encounters an event in a program. The delegating object is often a responder object—that is, an object inheriting from NSResponder in AppKit or UIResponder in UIKit—that is responding to a user event. The delegate is an object that is delegated control of the user interface for that event, or is at least asked to interpret the event in an application-specific manner. …

The programming mechanism of delegation gives objects a chance to coordinate their appearance and state with changes occurring elsewhere in a program, changes usually brought about by user actions. More importantly, delegation makes it possible for one object to alter the behavior of another object without the need to inherit from it. The delegate is almost always one of your custom objects, and by definition it incorporates application-specific logic that the generic and delegating object cannot possibly know itself. …

Requirement: a protocol
In order for me write sample code implementing the delegation design pattern, I’ll need a “protocol.” Refer to my article on protocols and remember that, as Apple puts it (my emphasis added):

Delegation is a design pattern that enables a class or structure to hand off (or delegate) some of its responsibilities to an instance of another type. This design pattern is implemented by defining a protocol that encapsulates the delegated responsibilities, such that a conforming type (known as a delegate) is guaranteed to provide the functionality that has been delegated. Delegation can be used to respond to a particular action, or to retrieve data from an external source without needing to know the underlying type of that source.

Apple emphasizes that:

A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. Any type that satisfies the requirements of a protocol is said to conform to that protocol. …

Explaining the code

NOTE: Keep referring to my prose and quotations above to remind yourself about the very important terminology — words, definitions — I’m using in the following discussion.

Piece: the delegating object
I’m going to build a class that implements a status/progress indicator, the StatusWheel class, something that can be displayed on screen to tell the user, “The app is performing some process that may delay the app’s responsiveness.” This will be the “delegating object,” as defined above, that “keeps a reference to the other object–the delegate–and at the appropriate time sends a message to it.”

Piece: the delegate protocol
A protocol needs to be defined. Remember that the delegation “design pattern is implemented by defining a protocol that encapsulates the delegated responsibilities, such that a conforming type (known as a delegate) is guaranteed to provide the functionality that has been delegated” (my emphasis added). This will be the StatusWheelDelegate protocol.

Piece: the delegate
I’m going to subclass a UIViewController and make it adopt — conform to — the the delegate protocol StatusWheelDelegate. Remember that the delegation “design pattern is implemented by defining a protocol that encapsulates the delegated responsibilities, such that a conforming type (known as a delegate) is guaranteed to provide the functionality that has been delegated” (my emphasis added). I’ll call this class ViewController (my, how original).

Code demo

Here’s what the app I’m building does:

Here’s the app’s output to the console:

Writing the code

Piece: the delegating object
Let’s look at the code for the delegating object, StatusWheel, which can display a status/progress indicator. I keep a weak reference to the delegate object (of type StatusWheelDelegate) for two reasons: 1) to allow a StatusWheel class instance to operate without a delegate (sending a message to nil doesn’t do anything in Objective-C), and 2) to prevent a retain cycle forming between the delegating object and delegate.

Here’s StatusWheel.h — and note the weak “delegate” property:

Here’s StatusWheel.m — and note where the delegate variable is sending messages like [self.delegate wasTapped:self];:


Piece: the delegate protocol
StatusWheelDelegate is the delegate protocol. You can conceptualize a protocol as a contract or promise that you can apply to a class, structure, or enumeration. Below, I will enter my ViewController class into a contract with the StatusWheelDelegate protocol, and the ViewController class promises to fulfill the contract by implementing the methods or member variables that StatusWheelDelegate requires be materialized or fulfilled, i.e., implemented.

Here’s StatusWheelDelegate.h — and notice the forward declaration of class StatusWheel (homework for you):

More homework: Why do you think I’ve specified a pointer to the StatusWheel object in each method declaration?

Piece: the delegate
My ViewController class adopts — conforms to — the delegate protocol StatusWheelDelegate. Notice that:

1) it has an instance of StatusWheel (StatusWheel* statusIndicator);

2) it sets the StatusWheel instance’s member variable delegate to self; and,

3) it provides customization of StatusWheel by allowing me to do whatever I want when those protocol methods are called, like dismissing the status/progress indicator from screen when it gets tapped.

Here’s ViewController.h:

Here’s ViewController.m:

Wrapping up

I want you to thoroughly read and digest my initial discussion about delegation, follow some of the links, and read some of my suggested articles. Notice I’m not explaining every little detail. When looking at the code, I want you to think about what’s going on. Look something up in one of my references or find others if you don’t understand a concept. Write your own delegation code.

Finally, I had promised a more advanced example of delegation. Well, here it is: “Using Swift extensions to manage complexity, improve readability, and increase extensibility (UICollectionView, protocols, and delegates)”.

Author: Andrew Jaffee

Avid and well-published author, software engineer, designer, and developer, now specializing in iOS mobile app development in Objective-C and Swift, but with a strong background in C#, C++, .NET, JavaScript, HTML, CSS, jQuery, SQL Server, MySQL, Oracle, Agile, Test Driven Development, Git, Continuous Integration, Responsive Web Design, blah, blah, blah ... Did I miss any fad-based catch phrases? My brain avatar was kindly provided by http://icons8.com under a Creative Commons Attribution-NoDerivs 3.0 Unported license.

Leave a Reply

Your email address will not be published. Required fields are marked *