Press "Enter" to skip to content

Basic Delegate Example

There are two things that I have recently grown to love when it comes to writing iOS code and those are Protocols and Delegates. If you written anything with a UITableView in it , then you’ve used Protocols before. For instance, cellForRowAtIndexPath is in fact a method that is defined in the UITableViewDataSource protocol. You’ve been using protocols this whole time and didn’t even know it, or maybe you did. So how do you make your own Protocol and Delegates? It’s actually fairly boilerplate and super simple. Here is a simple example.

Definition
[sourcecode language=”objc”]
#import <Foundation/Foundation.h>

@protocol MyClassDelegate <NSObject>
// Required means if they want to use the delegate they
// have to implement it.
@required
– (void)taskComplete:(BOOL)complete;
@end

@interface MyClass : NSObject
{
// We don’t know what kind of class is going to adopt us at
//compile time, that’s why this is an id
id<MyClassDelegate> delegate;
}

@property (nonatomic, assign) id delegate;

– (void)taskComplete;
– (void)doSomeTask;

@end
[/sourcecode]

If you’re curious as to why you see the assign property here check this great post on StackOverflow

Implementation

[sourcecode language=”objc”]
#import "MyClass.h"

@implementation MyClass

// Be sure to synthesize your instance variable
@synthesize delegate;

// Method used to call to our delegate and let it do the work.
– (void)taskComplete
{
// Sanity check, did they set the delegate?
if([self delegate] != nil)
[[self delegate] taskComplete:YES];
}

// Do some task like let a timer run and call our method when done.
– (void)doSomeTask
{
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(taskComplete) userInfo:nil repeats:YES];
}

@end
[/sourcecode]

Ok, the majority of the boilerplate is out of the way and we just need to write something that will actually adopt our protocol. The adopter will be the one who called MyClass to do some task and will be expecting MyClass to let it know when it’s done. This is why protocols are so great. Suppose you have a rather complex project and don’t want to create lots of bidirectional linkages between your classes, in that case delegation like this is going to be your best friend. It’s like having function pointers ad callbacks, but the communication goes both ways easily. Time to adopt our protocol and actually use it in a class.

[sourcecode language=”objc”]
/* MyDelegateAdopter.h */
#import <UIKit/UIKit.h>
#import "MyClass.h"

// Only reason I’m using a UIViewController is to have a place to set
// the delegate. This could be any class.
@interface MyDelegateAdopter : UIViewController
{
MyClass *myClass;
}

/* MyDelegateAdopter.m */
#import "MyDelegateAdopter.h"

@implementation MyDelegateAdopter

-(void)viewWillAppear:(BOOL)animated
{
myClass = [[MyClass alloc] init];
// Very important. If we don’t let myClass know who the delegate
// is we’ll never get the protocol methods called to us.
[myClass setDelegate:self];
[myClass doSomeTask];
}

// Delegate Method, this will get called when [myClass doSomeTask]
// completes.
– (void)taskComplete:(BOOL)complete
{
if(complete)
NSLog(@"Yay!");
else
NSLog(@"Boo!");
}
[/sourcecode]

Well, that’s about it. Pretty easy to setup, but great tool to have. Once you get used to using them in your own codebase you’ll wonder how you lived without leveraging them. If you want to read more check out cocoanetics for some info on delegate messaging in iOS with respect to the background task switching.

12 Comments

  1. Cocoanetics Cocoanetics May 5, 2011

    Hi, I wonder what the function of “nontoxic” is in a property definition …

    • Chris Chris May 5, 2011

      Oops. Sorry about that, should have been nonatomic. All fixed now and thanks for pointing that one out.

  2. Andy Andy January 8, 2013

    Chris – This was awesome – as a seasoned programmer new to IOS, I just could not get how delegates worked. All the examples I’ve found (and there are plenty) were so involved and confusing. Yours was a breath of fresh air and though I haven’t mastered it, I now have it working. Thank you so much

    • Chris Chris January 8, 2013

      That’s awesome, glad this post helped you. I often run into the same thing with tutorials and sample code. Sometimes people make it overly complicated without bothering with the basics. Haven’t posted in awhile, but I’m hoping to do a post on Storyboards and UICollectionViews soon. Thanks again for the feedback.

  3. Sepp Sepp February 27, 2013

    Great writeup. But I have one question.

    In other articles that describe protocols/delegates, the header of the class that adopts the protocol looks different.

    Your class “MyDelegateAdopter.h” looks like this:
    @interface MyDelegateAdopter : UIViewController

    Other articles always included the protocol here. So, I would have thought it should look like this:
    @interface MyDelegateAdopter : UIViewController

    Can you explain why the Protocol mention of is not needed?

    • Sepp Sepp February 27, 2013

      Um, for some reason the comment system doesn’t allow tags. Let’s see if this works. What I meant to say was, I think the MyDelegateAdopter.h should look like this:

      @interface MyDelegateAdopter : UIViewController -MyClassDelegate-

      (Since I can’t use the less than/greater than tags, I used the -)

      • Chris Chris February 27, 2013

        That should actually be there. It just explicitly says that the MyDelegateAdopter adopts the methods the protocol needs. Nice for say compile time warnings. The version of XCode that I used to write this post let this fly, but I’ll give the code a go with the latest version when I get home.

        At runtime, the [[self delegate] taskComplete:YES] is just going to call taskComplete on that object. If it didn’t exist, say the we called respondsToSelector and it returned NO, then the app would not be too happy. In the latest version of iOS it won’t take your app down anymore which is nice, but you will see an exception during debugging.

        It’s always best to <MyClassDelegate> to let everyone know your class implements the methods of the delegate. Thanks for pointing this out and sorry for the confusion.

  4. Emre Emre May 2, 2013

    A very nice and straightforward explanation. Well said. Respect!

  5. drlobo drlobo October 23, 2013

    setDelegate is not defined and you have not stated that the class even implements a protocol

  6. lee smith lee smith May 16, 2014

    YEP, YEP, YEP
    Ditto the comment about new programmer and Delegates.

    Now, then can you steer me to a TOME which discusses the many uses of delegates for the ordinary programmer [not including the pre packaged stuff like UITableView, UIPicker?

    In particular, I want to communicate between view controllers, especially when sucking up some date [WEB] in most formats [JSON, etc], storing and using the data in any place of my widget.

    Thanks again … and I am a [very old] Rocket Scientist turned computer NERD

    • Aksdash Aksdash June 12, 2014

      I have somewhat newbie in ios I have been using delegates but still I was not clear with basic concepts, all tutorials confused me. Now I really got it thank for simple basic tutorial…..

Leave a Reply

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