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];
精彩评论