开发者

Invoke methods declared in protocol from the class implementation

I've开发者_StackOverflow中文版 created a protocol named RecDelegate that's consisted of a method "- (void) doSmtng". The protocol is defined in rec.h just before the rec interface declaration.

When I create a new application and adopt the RecDelegate to the new appDelegate, I can implement my own doSmtng, as needed to be.

What I don't understand is how can I invoke the doSmtng method from the rec.m (implementation of the class in which the protocol is defined...) - Meaning, how can I "Fire" the doSmtng in such a way that the new appDelegate's implementation will be triggered.

Hope what I said is relatively clear ... ;)

Thanks, Guy.


There are two controllers below showing how to trigger an event from one to the other. Wherever there is a comment "//HERE", it indicates there is delegation-related code.

SENDER OF DELEGATE

SecondViewController.h

#import <UIKit/UIKit.h> 

@protocol SecondDelegate <NSObject> // HERE
  @optional
    -(void)MessageReceived:(NSString *)msg;
@end


@interface SecondViewController : UIViewController {
    id<SecondDelegate> secondDelegate; // HERE
}

@property (assign) id<SecondDelegate> secondDelegate; // HERE

-(IBAction)trigger:(id)sender;

@end

SecondViewController.m

#import "SecondViewController.h" 

@implementation SecondViewController

@synthesize secondDelegate; // HERE

-(IBAction)trigger:(id)sender {
    if (self.secondDelegate != NULL && [self.secondDelegate  respondsToSelector:@selector(MessageReceived:)]) { // HERE
        [secondDelegate MessageReceived:@"my message"]; 
    }
}

RECEIVER OF DELEGATE

FirstViewController.h

#import <UIKit/UIKit.h>
#import "SecondViewController.h" // HERE

@interface FirstViewController : UINavigationController <SecondDelegate> // HERE

-(void)MessageReceived:(NSString*)msg; // HERE

@end

FirstViewController.m

#import "FirstViewController.h"
#import "SecondViewController.h"

@implementation FirstViewController

 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        // Custom initialization
        [self.view setBackgroundColor:[UIColor greenColor]];
        SecondViewController *second = [[SecondViewController alloc] init];
        [self pushViewController:second animated:YES];
        second.secondDelegate = self; // HERE
        [second release];
    }
    return self;
}

-(void)MessageReceived:(NSString *)msg { // HERE
    int y = 0; // HERE IT IS !
}


You need to tell your Rec object that it should treat your AppDelegate as its delegate:

[rec setDelegate:appDelegate];

This could be done via Interface Builder or just after the Rec object is created.

Then, when the Rec object sends the delegate message to its delegate, the receiver will be your AppDelegate instance:

[[self delegate] doSmtng];

If the message the Rec object is sending to its delegate were an optional protocol message, it would instead be sent like this:

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

The delegate will usually be declared something like:

@property(assign, nonatomic) id<RecDelegate> delegate;

Because it is not retained, in -dealloc, the Rec object only needs to nil it out, not release it:

delegate = nil;


Another way to do something like that is using NSNotificationCenter

in your RecDelegate init method add:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSmtng) name:@"someNotification" object:nil];

and in any another place / any class call

[[NSNotificationCenter defaultCenter] postNotificationName:@"someNotification" object:nil]; 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜