The Basics of Protocols and Delegates

Fri, Apr 16

Apple offers a good overview of working with protocols in their Objective-C Programming Reference. However, sometimes a simple working example can go a long ways…

Introduction

Protocols can be helpful in a number of scenarios, a common usage is to define methods that are to be implemented by other classes. A familiar example is when using a tableview, your class implements the cellForRowAtIndexPath method which asks for cell content to insert into a table – the cellForRowAtIndexPath method is defined within the UITableViewDataSource protocol.

Let’s walk through a very simple example of defining and adopting a protocol.

Protocol Definition

Here is an example of a protocol which includes one method, notice the instance variable delegate is of type id, as it will be unknown at compile time the type of class that will adopt this protocol.

#import <Foundation/Foundation.h>
 
@protocol ProcessDataDelegate <NSObject>
@required
- (void) processSuccessful: (BOOL)success;
@end
 
@interface ClassWithProtocol : NSObject 
{
 id <ProcessDataDelegate> delegate;
}
 
@property (retain) id delegate;
 
-(void)startSomeProcess;
 
@end
Protocol Implementation

Inside the implementation section for the interface defined above we need to do two things at a minimum – first synthesize the delegate instance variable and second, call the method defined in the protocol as needed (more on that in a moment).

Let’s look at a bare bones implementation of the ClassWithProtocol.m:

#import "ClassWithProtocol.h"
 
@implementation ClassWithProtocol
 
@synthesize delegate;
 
- (void)processComplete
{
  [[self delegate] processSuccessful:YES];
}
 
-(void)startSomeProcess
{
  [NSTimer scheduledTimerWithTimeInterval:5.0 target:self 
    selector:@selector(processComplete) userInfo:nil repeats:YES];
}
 
@end

Understand this is a rather contrived example – the intention is to show how/where one might use a protocol. For the sake of discussion assume you have a class that is processing (or downloading) some type of data. Further, assume this class is called from another class to begin the processing. Chances are, at some point the caller will want to be notified that the class processing the data is done, this is where the protocol comes in.

In the calling class, the method defined in the protocol, processSuccessful, will be implemented and will be called from the object doing the processing, once it is complete.

For this example, inside the class where the protocol is defined, I have one method, startSomeProcess, which simply starts a timer and calls processComplete after 5 seconds. Inside processComplete the calling object will be notified through its delegate that the process is done.

Adopting the Protocol

To keep the example short, I am using the applicaton delegate as the class that adopts the protocol. Here is how the app delegate looks:

#import <UIKit/UIKit.h>
#import "ClassWithProtocol.h"
 
@interface TestAppDelegate : NSObject <UIApplicationDelegate, ProcessDataDelegate>
{
  UIWindow *window;
  ClassWithProtocol *protocolTest;
}
 
@property (nonatomic, retain) UIWindow *window;
 
@end

A few things to note – ProcessDataDelegate is defined as part of the interface, which signifies that this class will adhere to the protocol. Looking back to the code for defining the protocol, notice that I added @required to the definition, which means that any class that adopts the protocol must implement the processSuccessful method (you will receive a compile warning if you don’t).

Here is the implementation of the app delegate and the required method for the protocol:

#import "TestAppDelegate.h"
#import "ClassWithProtocol.h"
 
@implementation TestAppDelegate
 
@synthesize window;
 
 UITableViewDelegate
 
- (void)processSuccessful:(BOOL)success;
{
  NSLog(@"Process completed");
}
 
- (void)applicationDidFinishLaunching:(UIApplication *)application 
{   
  // Create and initialize the window
  window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
 
  protocolTest = [[ClassWithProtocol alloc] init];
  [protocolTest setDelegate:self];
  [protocolTest startSomeProcess];
 
  [window makeKeyAndVisible];
}
 
- (void)dealloc 
{
  [window release];
  [super dealloc];
}
 
@end
How it all works

Things goes as follows: the app delegate will create a new instance of the ClassWithProtocol object. It sets itself as the delegate and then calls the startSomeProcess method. At some point in the future, when the protocolTest object has completed its work – after the 5 second timer has fired – it will call the processSuccessful method in the app delegate to let it know it is done processing.

Download Xcode Project

You can find a complete (albeit trivial) working example here: Protocol Xcode Project

50 comments

Great tip

by Sheng on Apr 16, 2010. #

Hi,

Thanks for the post, and I have a question. Can I use the @protocol for interfacing between classes ? The main goal is to do some dependency injection like in Java (with interfaces and implements).

I’ve got the following classes SignUpServiceImpl (which has a interface called SignUpService) and a class ServiceHelperImpl (interface is ServiceHelper).

I don’t want to hard wire both implementations together so I use a @protocol in ServiceHelper which is implemented by ServiceHelperImpl. Then SignUpServiceImpl is initialized with ServiceHelper like this: – (id)initWithHelper:(ServiceHelper *)myServiceHelper

Is it possible what I’m trying to accomplish ? It looks so much easier in Java….

Thanks in advance!

Best regards,

Rutger

by Rutger on Feb 19, 2012. #

Good article, but I think its usually considered better to use assign rather than retain when declaring a property that is to be a delegate. If object A is a delegate for object B, then if A is released by its owner, B does not need to reference it anymore. It is also a good practice in dealloc for A, to set any delegate properties that point to A, to null. That way when the object goes to notify A, after it has been released, it doesn’t get an error.

for more info, check the first answer here – http://stackoverflow.com/questions/918698/why-are-objective-c-delegates-usually-given-the-property-assign-instead-of-retain

by Cooper on Apr 16, 2010. #

thanks for giving the such useful kind of information about the protocols thakning you
ohh! !!!!!!my greatfulthanks to u mydear it’s very nice lik to retrieve theinfo

by narender on Sep 22, 2011. #

Delegation is a very nice design pattern. Wen you build a complex project and want to avoid bidirectional links between all classes, then as described in this post, delegation is your friend.

by romain on Apr 18, 2010. #

Besides not retaining your delegate (see coopers comment) it’s always a good idea to enforce the protocol on the property declaration as well:

@property (nonatomic, assign) id delegate;

It’s smart to let your protocol inherit from NSObject protocol, this gives you easy access to common methods such as respondsToSelector & performSelector. But it’s an even better idea to declare your delegate ivar not as id but as NSObject* as this also allows gives you access to common NSObject methods not defined in the NSObject Protocol (like performSelectorOnMainthread: and performSelector:AfterDelay:).

by ullrich on Apr 20, 2010. #

thanks for giving the such useful kind of information about the protocols thakning you

by narender on Sep 22, 2011. #

This is really good article. I went through it and it helped to understand delegates and protocol and how it works together. Thanks and looking forward for such cool articles

by SK on Apr 26, 2010. #

A really important tip if you’re trying this for the first time ..

DONT FORGET the line of code along the lines …

blah.delegate = self;

in the actual class where you are USING the delegate!!!!!!!!!!

You can struggle for hours wondering why it is not working if you forget that, since, without that line everything is actually working perfectly at compile and runtime… it just does nothing!

by Stevie on Apr 30, 2010. #

This article and your hint are very useful! It costs me hours and I got a lot of grey hairs more. Now it is up and running! Thank you both!!!

by Valentin on Feb 18, 2011. #

Thank you Stevie for sharing the important tip!

Like Valentin, I have also spent hours searching for a reason that the function defined in my protocol never gets called when everything supposedly works fine. Much appreciated!

by Milly on Mar 28, 2011. #

Seriously, stevie, thanks for this very useful tip.Me too spent hours wondering why isnt it working until came across your comment.

by Mayank on Apr 19, 2011. #

Even better to create an initWithDelegate:(NSObject*) initializer as to help you not forget that critical assignment.

by Stephen Burns on Aug 13, 2011. #

Thank you Stevie the most important tip without which all is waste ;)

by Ajay on Aug 17, 2011. #

Thanks for removing the mystery. I tried to implement this myself and was lost. I tried to look at examples and the Apple documentation. It was overwhelming. This was simple. You casued my headaches to go away.

by Jean-Paul on Jun 13, 2010. #

Brilliant!

by Peter on Jun 17, 2010. #

Thank you for taking the time and sharing your knowledge.

In the .h file (@interface TestAppDelegate) you have

@class testAppObject;

what role does this class have in the protocol? I do not see where it is referenced again…

This was a very helpful lesson, but my question lingers on my mind.

by davidf on Jul 25, 2010. #

David, good call…typically this a forward reference for the compiler, however in this example it is not needed. I removed the line of code in the example shown above.

by John Muchow on Jul 25, 2010. #

Oh my…. Thanks so much for explaining this, I love you!
I really was about to trash my MBP, trying to figure out how Modal Views
really work. I want to add a cell to a table, using a Modal View
(I’m a n00b-iOs-developer) and just couldn’t understand how Apple
wants me to do it (delegating from the modal-View back to the
TableView that initiates this in the first place).
Thanks to you I now understand ObjC-Delegation – you made my day!

by El el on Nov 3, 2010. #

Great Thanks..Really Cool Tutorial.

by Mr.Black on Jan 26, 2011. #

Great tutorial, straight to the point with simple example code. And source code to boot! And the source actually works lol. So often you see tutorials like this and after spending time on trying the code their way it doesn’t work. Hat’s off on all counts.

by maconbot on Mar 29, 2011. #

Hi John Muchow,

Good tutorial really,
One small question, may be silly

In the method -processComplete,
I used the below lines
[delegate processSuccessful:YES];

Instead of
[[self delegate] processSuccessful:YES];

No issues as-such, Can you tell me the significance of using the former one in your code?

Thanks,
Prem

by PremKumar.Jerome on May 10, 2011. #

It’s for the same reason any developer would choose to access a property rather than its ivar. For that specific line of code, there’s no difference in outcome, you’ve just chosen to grab the delegate through it’s property.

by Stephen Burns on Aug 13, 2011. #

In this example there is no difference. But in general, [[self delegate]…] is to be preferred, since that will always get the right delegate, the UIApplication’s property ‘delegate’, which is the one that you went through all the trouble to set using “[protocolTest setDelegate:self];”

by Matt J. on Feb 2, 2012. #

Nice post. One thought, if your not using @required is that you might want to use some introspection to stop things crashing out if you only use half the delegate methods, something like…

if ([[self delegate] respondsToSelector:@selector(processSuccesfully:)]) {
[[self delegate] processSuccesfully:YES];
}

by PJ on May 31, 2011. #

Thank you!!! I’ve taken a number of runs at trying to understand the Delegation pattern, always unsuccessfully until today.

Your article finally helped the concept gel for me. :)

by jhoffman on Jun 23, 2011. #

Thanks!!!

by Martin on Jul 25, 2011. #

What a simple, clear, lucid explanation! Bravo! Great example code that included all necessaries, and no fluff. The combination of your useful code and clear writing make this one of the best tutorials I have found, and certainly the best on delegation. As a result of your tutorial, I have delegation working in my code.

Thanks.

by James on Jul 25, 2011. #

Looking back to the code for defining the protocol, notice that I added @required to the definition, which means that any class that adopts the protocol must implement the processComplete method (you will receive a compile warning if you don’t).

is this certainly correct? isn’t processSuccessful the one that must be implented? or i am missing something?

by kiki on Aug 19, 2011. #

It is correct, but a little misleading. ‘@required’ is in fact the default, so both processSuccessful and processComplete are required.

For his sample code, this is exactly what he wants: both to be required.

by Matt J. on Feb 2, 2012. #

I am unable to use the retrieved value in UITableViewController cell, Can you explain why?

by Veer on Sep 5, 2011. #

Thanks so much..for awesome tutorial of protocol and delegate

by Sachin Thakur on Sep 21, 2011. #

I was skimming this tutorial and didn’t understand a thing. After reading it carefully line by line, it now makes perfect sense!

I think for someone new to this, but not new to programming, the best way to describe what it does is a “call back”. i.e. Object A creates Object B and tasks it to do something. Object A would like to know when Object B is done, but rather than it keep asking Object B at set intervals: “Are you done yet? Are you done yet? Are you done yet? etc…” (polling), it instead just says to Object B, “This is a reference to me, use this reference to let me know when you’re done”.

by Grant on Oct 13, 2011. #

And indeed, callbacks are a very frequent application for delegates. Perhaps the various tutorials and reference materials on the apple developer site should make mention of this more often. But delegates have other applications, too. And they add something above a pure vanilla callback. That “semantic sugar” must be worth something;)

by Matt J. on Feb 2, 2012. #

I pulled my hair out for days trying to get this to work. I finally found this on the Apple site:

https://developer.apple.com/library/mac/#qa/qa1554/_index.html

which made me try one more thing. I added an IBOutlet to my delegate like this:

@property (nonatomic, assign) IBOutlet id delegate;

I hooked the it to the file’s owner of the view controller that is the delegate for my BubblList controller.

I am new to Objective-C, so this may have been obvious to those more experienced, but the example doesn’t show it this way and I didn’t find it in other examples either. Does anyone know why? Is the outlet unnecessary in the example because the delegate is the AppDelegate? I’d love to know why the syntax in this example seemed to work for other people, but not for me. (I’m running Xcode 4.1 and iOS 4. 3).

Thanks!

by Sue on Oct 22, 2011. #

Simple and nice example for new IOS develovers like me .. :-) Thank you ……..

by Abhay on Nov 7, 2011. #

Best Example of Protocols its reduce the programing code

by Girish on Nov 23, 2011. #

Great post, very very useful … thank you

by Alessandro Dellanna on Mar 14, 2012. #

Thanks John – by removing all the “fluff” you’ve made this very simple to understand and implement.

by Simon on Mar 17, 2012. #

In your good tutorial…i think there is a mistake..correct me if i am wrong.
you say that “@required to the definition, which means that any class that adopts the protocol must implement the processComplete method” when actually its the method “processSuccessful” that in my view should be implemented. Do spare some time and reply me if i am wrong ok.
Thanks again for such a lovely tutorial.

Bye
:p

by hassan on May 6, 2012. #

Thank you Hassan, that looks correct. I’ve made the update to the post.

by John Muchow on May 6, 2012. #

Great example! Thanks for taking the time to post it. Works a charm.

by John Sneddon on May 24, 2012. #

great tutorial! just copied and pasted and fully worked! :)

ty so much..

by iremk on Jul 2, 2012. #

Thank you so much..Good article

by vineela on Aug 23, 2012. #

Thank you, it’s really a good tutorial

by Truong Ho on Nov 15, 2012. #

Its fantastic tutorial…awesome…everything covered here..

Hats off to you…

by Jayaprakash on Nov 27, 2012. #

Hats of 2 u for fantastic tutorial

by Anup on Feb 14, 2013. #

Hi John,

It appears to me that you might need to update this tutorial for people who are using the latest version of Xcode. I’ve noticed that this article talks about synthesizing. I don’t believe you have to synthesize and/or release things anymore, because Xcode now allows the use of automatic reference counting. Then again, I am a novice developer who is building a location-aware app.

by Monty on Mar 12, 2013. #

Thanks Monty, I appreciate the comments. Yes, Xcode can now automatically synthesize properties, however, as a developer you can still write the code to synthesize. Similarly, older code that has synthesize already defined will continue to work. The same idea goes for ARC, this is just one means of managing memory. I personally have not moved to ARC as I’ve been doing the retain/release programming for many years, so the change to ARC is low on my priority list.

by John Muchow on Mar 12, 2013. #

thank u it healped me a lot.. keep going with ur “helping hand”

by vimal francis on Mar 25, 2013. #