Delegation Pattern in Objective-c and writing Custom Delegates

Delegation pattern is the most important topic in Obj-c.We need delegates everywhere when we want to create apps for iOS/Mac OS X. I have wrapped up The best explanation from net That helped me to Understand The delegates.

What is delegate ?

Delegation as a clean and simple way of connecting objects and helping them to communicate with other. In other words, delegation is a dating service for Objective-C objects.

Apple makes it more cleaner here But I recommend it to read it later after reading my full post

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.

if It does not make any sense Then we can Try with Some cool examples.

Example 1 :

Let’s say we have two objects, Brain and Beer Bottle, Brain is the object we use to manage the entire Body application, it handles all of the important tasks such as poop, eat, drink, sleep etc. Beer Bottle is attached to body but it doesn’t know what Brain is thinking, likewise, Brain has no idea what Beer Bottle is thinking.

Brain is using Beer Bottle’s attributes to satisfy itself while it’s watching TV, but the problem is that brain is so distracted by the tv that it can’t pay attention to when beer is going to run out. This could all end in disaster, Brain needs to know when beer is empty so that it send body to the fridge and initialize another instance of Beer Bottle.

Brain can use the drink function to lower Beer Bottles liquid variable, but once liquid reaches 0, Brain needs to know about it, this is where delegates come into action, we can use a Beer Bottle Delegate. Brain can listen out for the Beer Bottle Delegate telling brain that the bottle is empty, all we need to do is simply tell Brain to listen out for Beer Bottle telling it’s delegate that is empty and Brain can react to it. This well thought out and illustrated diagram shows all of this in action:

Example 2:
My favorite way to explain how delegates work involves animals.

Let’s say you are going to create a particular bird. You start with a predefined class definition of a bird (provided in the existing framework as, say, CFBird). The existing framework class assumes all birds have certain things in common — they hatch and grow the same, poop the same, fly the same, and lay eggs the same way, etc. (tee hee, I said poop.  ) But different birds look different, are different sizes, chirp differently, eat different things, and may mate differently.

So let’s say Apple provided you with the basic bird class (with hatching, growing, pooping, flying and egg-laying behavior already built in).

Here now in this more advanced age of object-oriented design, there’s a concept (design pattern) called “delegation” and it’s a cool way to easily implement custom classes, assuming ahead of time that you’ll likely never need to worry about anything else about creating birds other than specifying how they differ from each other — how they look (size and color) and how they chirp, eat and mate.

So, the people who designed the CFBird class have set up a “protocol” which specifies the “delegate methods” (kinda like “callbacks” in C) which is all your new class will need to implement to create your custom bird, and you’re done! Basically the class is going to call into your code when your particular bird is drawn, when it chirps, eats and mates. These tasks are “delegated” to you in your subclass of CFBird.

Everything else is handled for you, and you only need to concern yourself with what is different about your bird, and forget about what is the same amongst all birds, simplifying your life and making things more consistent.

In your code, when you specify your new class of bird, in the @implementation you’ll make reference to a <protocol>, and by doing so you are telling the system that you agree to implement the methods specified in that protocol which will detail exactly how your particular bird is going to look, chirp, eat, and mate. Done and done.

The subclassing comes first, and the possible delegate methods follow if you specify a protocol to follow.

Example 3 :

You have a class, that takes care of some calculations. Depending on how complicated these are, they can take up more or less time. Once the calculations are done, you want to send a feedback message to the class, that triggered the process. Using a custom delegate will allow you to receive that message without implementing the calling class into your calculations class. The big advantage is, that you will be able to use your calculations class in any class, send feedback message through the delegate and keep your code nice and clean.

Implementation:

Using the existing delegates is easy, take this code for example, it simply tells the current class that it needs to listen out for the UIActionSheetDelegate so that we can handle button clicks on an action sheet.


- (void)viewDidLoad {

	[super viewDidLoad];

	UIActionSheet *actionSheet = [[UIActionSheet alloc]
					initWithTitle:@"Delegate Example"
					delegate:self // telling this class to implement UIActionSheetDelegate
					cancelButtonTitle:@"Cancel"
					destructiveButtonTitle:@"Destructive Button"
					otherButtonTitles:@"Other Button",nil

	[actionSheet showInView:self.view];

	[actionSheet release];

}

Our action sheet will simply show when the view loads, and this is how we handle the delegate so that we can do something when a button is clicked, it’s easy..


- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
	NSLog(@"hello world!");
}

Looking good so far, but hold up one second, don’t get carried away. We still need to make one little change to our code, currently we have told our class to implement the UIActionSheetDelegate by using delegate:self . But we forgot to tell our class to implement the UIActionSheetDelegate protocol so that it knows which functions are available to it! How do we do that i hear you cry? it’s also easy, head to your .h file and simply do the following, for the not so eagle eyed, <UIActionSheetDelegate> is what has been added:

@interface DelegateExampleViewController : UIViewController <UIActionSheetDelegate> {

}

ok we Just used The existing delegates.We can write Our own custom delegates for our classes.

Writing custom delegates :

I’d like to give a short demonstration of how to create a class with a delegate. For the purposes of this tutorial, we’ll call our class Printer.

The interface to Printer starts out as the following:


//
//  Printer.h
//  Printer
//
//  Created by asadullah-hel Galib on 9/15/11.
//  Copyright 2011 enroyed. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Printer : NSObject{

}

-(void) printData;

@end

Now, we need to modify this interface to include a delegate protocol:


#import <Foundation/Foundation.h>
@class Printer;

@protocol PrinterDelegate <NSObject>

-(void) finishPrint;

@end

@interface Printer : NSObject{
    id <PrinterDelegate> delegate;
}
@property (nonatomic,assign) id<PrinterDelegate> delegate;
-(void) printData;

@end

The implementation for “Printer” might look like this:

#import "Printer.h"

@implementation Printer
@synthesize delegate;

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

-(void) printData{
    for (int i=0; i<15; i++){
     NSLog(@"This is printData");
    }

    [delegate performSelector:@selector(finishPrint)];
}

@end

Finally, the class that implements PrinterDelegate might have its interface declared as follows: (here we implement it in UIViewController)


#import <UIKit/UIKit.h>
#import "Printer.h"

@interface PrinterViewController : UIViewController<PrinterDelegate> {

}

@end

Now some class Must Implement “finishPrint” function because Its not Optional protocol function.Here we implement it in “PrinterViewController.m” file:


- (void)viewDidLoad
{
    Printer *myPrinter = [[Printer alloc]init];
    myPrinter.delegate = self;  //we are pointing the delegate to self coz we are implementing the  "finishPrint" function into the same class.

    [myPrinter printData];

    [super viewDidLoad];

}

-(void) finishPrint{
    NSLog(@"print is completed");
}

Here if we dont write “myPrinter.delegate = self” Then the callback function “finishPrint” will not be triggered.So delegation is a technique to trigger The callback function in right time :D

Download the demo code here CustomDelegate

I hope that this has helped those who were struggling with the delegate design pattern.

This entry was posted in iOS. Bookmark the permalink.

9 Responses to Delegation Pattern in Objective-c and writing Custom Delegates

  1. Khlil Shehab says:

    I had hard time understanding delegation. However, when I read your tutorial, it became crystal clear. You have done an awesome job explaining the pattern and your examples are fun!

  2. nice post, all question marks are gone.. thank you.

  3. Sonu says:

    That was the best tutorial on delegate i have ever read. Awesome Work. Thanks a ton.

  4. Rob V says:

    well done!
    delegation is one of those things; difficult to “get into”, but once done you wonder why it ever was

    now the english may have trouble with your first metaphor, warm beer and all that…:)

  5. Thanks a lot!! really a greeeeat tuto!!

  6. Jason says:

    Thank you. so much. You saved me a lot of time

  7. Michael says:

    Just want to say big thanks!

  8. Mike says:

    Thanks man, this really cleared things up for me!
    Great tutorial :D

  9. This is really cool, i like the explanation part, i was struggling a bit hard to get out on this, however you have explained in properly. A big thanks.

Leave a Reply

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

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>