2

I am trying to learn, how to implement delegation pattern in objective C. But the discussion almost exclusively concentrates on the adoption of protocols and then implementing the delegate methods that come with particular protocol - or - the delegation principle alone - or protocols alone.

What I am unable to find, is a easy to understand material about how to write a class that will serve as a delegator. By that I mean the class, which the message of some event will come from and which will provide the protocol for receiving that message - kind of 2in1 description. (protocols and delegation).

For the purpose of my learning, I'd like to go along the following trivial example, using an iPhone, a Cocoa touch application and Xcode4.2, using ARC, no Storyboard or NIBs.

Let's have a class with name "Delegator", which is a subclass of NSObject. The Delegator class has NSString instance variable named "report" and adopts the UIAccelerometerDelegate protocol.In the Delegator implementation, I will implement the the delegate method

-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration 

This delegate method will create a NSString @"myReport" and store it in the report variable anytime there is an accelerometer event. Further, I want to have a second class named ReportsStorage (a subclass of NSobject), which can store some Nsstring (report) in its instance variable called latestReport. So far so good. Now lets get back to theDelegator Class. I'd like to implement a protocol in Delegator named ReportsDelegate which will notify the class that adopts it (the ReportsStorage class), that a report was generated and will pass this report through the delegate method, which should be (I believe) something like this

-(void)delegator:(Delegator *)delegator didCreateNewReport:(NSString *)report;

Can you please provide the code for Delegator Class (incl. the "delegate" property), that will achieve this, with a description what each line of code means?

Thanks in advance, EarlGrey

Earl Grey
  • 7,426
  • 6
  • 39
  • 59
  • possible duplicate of [How does a delegate work in objective-C?](http://stackoverflow.com/questions/1045803/how-does-a-delegate-work-in-objective-c) – vikingosegundo Dec 13 '11 at 00:14

1 Answers1

3

You'll need to declare the delegate property as an id<ReportsDelegate> type. That is, any object type (id) conforming to the ReportsDelegate protocol (<ReportsDelegate>). Then, if the delegate method is considered optional, check if the delegate responds to that selector before calling it. (respondsToSelector:).

Like so:

Delegator.h

#import <Foundation/Foundation.h>

// Provide a forward declaration of the "Delegator" class, so that we can use
// the class name in the protocol declaration.
@class Delegator;

// Declare a new protocol named ReportsDelegate, with a single optional method.
// This protocol conforms to the <NSObject> protocol
@protocol ReportsDelegate <NSObject>
@optional
-(void)delegator:(Delegator *)delegator didCreateNewReport:(NSString *)report;
@end

// Declare the actual Delegator class, which has a single property called 'delegate'
// The 'delegate' property is of any object type, so long as it conforms to the
// 'ReportsDelegate' protocol
@interface Delegator : NSObject
@property (weak) id<ReportsDelegate> delegate;
@end

Delegator.m

#import "Delegator.h"

@implementation Delegator
@synthesize delegate;

// Override -init, etc. as needed here.

- (void)generateNewReportWithData:(NSDictionary *)someData {

    // Obviously, your report generation is likely more complex than this.
    // But for purposes of an example, this works.
    NSString *theNewReport = [someData description];

    // Since our delegate method is declared as optional, check whether the delegate
    // implements it before blindly calling the method.
    if ([self.delegate respondsToSelector:@selector(delegator:didCreateNewReport:)]) {
        [self.delegate delegator:self didCreateNewReport:theNewReport];
    }
}

@end
BJ Homer
  • 48,806
  • 11
  • 116
  • 129