Check out our Bootcamp Schedule View Schedule

Protocols, part 1 : Why?

Mark Dalrymple

A comment from a reader of Objective-C Programming: The Big Nerd Ranch Guide came through on the forums, asking about Objective-C protocols. Specifically, why do we need them? Why do they exist?

As a reminder, a protocol is a list of methods that’s been given a name. The NSCopying protocol contains a single method copyWithZone:, while the NSCoding protocol contains encodeWithCoder: and initWithCoder:. You adopt a protocol by adding the protocol name in angled brackets after the class you’re inheriting from:

@interface BNRGroovyness : NSObject <NSCoding>

This @interface says that “BNRGroovyness inherits (is-a) NSObject, and so can be used anywhere an NSObject can be used. And also, it promises to implement the required methods in the NSCoding protocol.” The compiler will check your work to make sure you actually implement them. Of course, you don’t have to implement optional methods in the protocol unless you really want to.

Like many programming constructs, protocols are primarily a communication mechanism. They communicate to the compiler that these objects really can receive a particular set of messages. They also communicate to the reader of the code that this class has some higher-level semantics. “This class conforms to NSCoding, therefore I can encode and decode its objects into a data archive” or “Oh! This class conforms to UITableViewDataSource! I can use its objects to power a table view.” Xcode can also use protocol adoption to expand the list of autocomplete options, making it easier to correctly spell the names of the methods you’d be implementing.

Protocols allow for a kind of multiple inheritance in Objective-C. You don’t really inherit code from multiple classes, but you can inherit multiple contracts, stating that you’ll obey those contracts. If you’ve used Java, they’re just like Java interfaces, which interestingly enough were inspired by Objective-C protocols. So when you’re adopting multiple protocols, all the code is implemented in your class or comes via the single-inheritance chain.

Protocols come into their own when you’re handing an object to another object for it to do work. If you’re giving an object to an NSKeyedArchiver, that object needs to support NSCoding so that the archiver can serialize the object. If you’re giving an object to a UITableView, it needs to support UITableViewDataSource so that it can feed the table. This helps move some of the correctness tests from run-time (“oops, this object doesn’t implement -encodeWithCoder: . Time to crash!”) to compile time ("warning: sending 'BNRGroovyness *' to parameter of incompatible type: id<NSCoding>")

One very popular use for making your own protocols is setting up a delegate relationship between objects. Come back next time for details.

Not Happy with Your Current App, or Digital Product?

Submit your event

Let's Discuss Your Project

Let's Discuss Your Project