Protocols and Delegates

In the real world, there are times where you are required to follow strict procedures when dealing with certain situations.  Law enforcement officials are required to "follow protocol" when making enquiries or collecting evidence.  A child is required to "follow protocol" when knowing if it's OK to eat another cookie.  My roommate is required to "follow protocol" when making a decision as to whether or not he should be running through the apartment at 3 AM.

In the world of object-oriented programming, it's important to be able to define a set of behavior that is expected of an object in a given situation.  As an example, a table view is expecting to be able to communicate with a date source object in order to find out what it is required to display.  The data source object must respond to a specific set of messages that the table view might send.  The data source could be an instance of any class (for example, NSObject).  In order for the table view to know whether an object is suitable as a data source, it's important to be able to declare that the object implements the necessary methods.   Objective-c allows you to define protocols, which declare the methods expected to be used for a particular situation.

Protocol: An interface.  It's a promise that in anything that conforms to the promise will implement a set of methods.
Delegate/Data source: An object that implements the interface.  The data source supplies the data, the delegate supplies the behavior (which is what I discuss below).  This helps us decouple our objects.

Jim in this example is a child who is looking to either go in the pool, eat some cookies or play some video games.  He needs to first ask someone for permission.  This example shows how various classes are conforming to a protocol which in this case is conforming to "JimDelegate" as you will see in the code.  By doing this, Jim can ask anyones permission who conforms to the JimDelegate to do the things he wants to do. 

Below is the Jim.h file and Jim.m file (you will see in the .m file that Jim is calling on methods implemented by the delegate, we will get to that later).  Jim can ask permission to jump in the pool, eat a cookie or play video games.  Jim has a property named delegate of type id (meaning this could be of any class) which conforms to the JimDelegate.  But how do we create the JimDelegate?  See Below.

 

This is the JimDelegate.h file.  "@protocol ProtocolName <ProtocolToExtend>" is the line of code required in order to create a protocol.  Any objects that adopt this protocol are guaranteed to implement all of the below methods.  The <NSObject> after the protocol name incorporates the NSObject protocol, not to be confused with the NSObject class.

 

Below is an object (of type NSObject) called Maryann.  You will see in the Maryann.h file that she conforms to the protocol.  That is done with the following: "@interface Maryann : NSObject <JimDelegate>"  We will then bring in that delegates methods and implement them in the Maryann.m file as you will see below.

 

The below code is written in the AppDelegate.m main file in the didFinishLaunchingWithOptions method to show what is going on here.  We are creating a Jim Object named jim and a Maryann object named maryann.  For now, Aunt Pat has been commented out (her .m & .h files are identical to Maryanns).  The following methods being called on by jim are producing the three NSLog statements below.  Easy enough, but I'm showcasing this code to show how easy it is to have Aunt Pat become the delegate instead of Maryann (my mom) when my Mom has to go away somewhere (like go shopping and telling Aunt Pat to not let me use the computer).  If we didn't set up the delegate this way, then we would have to manually go throughout Jim's .h & .m file and change all of the code to directly speak with Aunt Pat.  Instead, with the below code we are able to easily setup our delegate which would be someone who conforms to the JimDelegate protocol.