I'm understanding how delegates work, had gone trough some examples, but now with a basic app for testing, it seems i haven't yet got it,
here my code:
Class defining protocol > *.h
#import <Foundation/Foundation.h>
@protocol protoPerra <NSObject>
-(void) dimeTuNombre:(NSString *) s;
@end
@interface MyClassic : NSObject {
id<protoPerra> _delegate;
}
@property (assign) id<protoPerra> delegate;
@end
Class implementing protocol> *.m
#import "MyClassic.h"
@implementation MyClassic
@synthesize delegate = _delegate;
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
[[self delegate] dimeTuNombre:@"pinguete"];
}
return self;
}
-(void) dealloc {
[_delegate release];
_delegate = nil;
[super dealloc];
}
@end
Class Adopting protocol:
#import "MyClassic.h" @interface MainViewController : UIViewController (protoPerra)
.m
#import "MainViewController.h"
@implementation MainViewController
-(void) dimeTuNombre {
NSLog(@"ss9!! tkt");
}
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *lava = [[[UILabel alloc] initWithFrame:CGRectMake(30, 100, 100, 20)] autorelease];
lava.text = @"lava ss9";
[self.view addSubview:lava];
MyClassic *pirr = [[[MyClassic alloc] init ] autorelease];
[pirr setDelegate:self];
}
-(void) dimeTuNombre:(NSString *)s {
NSLog(@"%@",s);
}
@end
so what is missing in this simple example to make it work with my delegate?
thanks a lot!
Please note i have used () insted of the <> [in the .h of the adopting class] as if i use the Chevrons, the code disappears
You call the delegate method (dimeTuNombre:) in MyClassic init, but the delegate is not set yet, so you either need to rethink when to call dimeTuNombre:, or refactor the MyClassic class to have a constructor like
instead of just simple init.
To clarify, in your current code you set the delegate in MainViewController.h when you do [pirr setDelegate:self]; - which sets the value "delegate" of the property of MyClassic to the current instance of MainViewController. Note that when you call MyClassic's init, the delegate isn't set yet, so the [[self delegate] dimeTuNombre:@"pinguete"]; call does nothing (delegate is nil at that point).
You could change your MyClassic constructor as follows:
Then instead of this:
You will do this:
This will work, but note that usually delegates are used for notifications of various kinds - like a button reporting it was clicked or a socket says it has received some data.
I think that Paul Hegarty from Stanford University gave a very good summary on how to use protocol in Lesson 9, development apps for iOS, fall session 2011(available in iTunes, check Paul's blog):
Paul also gave an example of how to use protocol in a calculator app.
First, the protocol is created:
Step 2). In the table view of CalculatorProgramsTableViewController.h, a delegate is defined as a weak linked id property:
By using the protocol, the table view will be able to send out message about a program is changed, but the view does not know about the graphic view. This is done in the next step.
Step 3). In the table view controller, the delegate is used to send message to out about the program changed:
Step 4). Where is the delegate was set? It is set in the calculatorGraphViewController (right view in the split view). When a segue is ready to push a pop up view(table view), it sets self as a delegate:
The graphic view does not know about the table view, the communication channel is built by the protocol, beautifully done without any coupling! In order for any delegate to call back by this protocol, the graphic view controller's .h file has to implement the protocol:
And the method of protocol is defined in the .m file in the next step.
Last step. The delegate's protocol method is implemented in the segue's controller. The protocol's method will be called when a row in table view is selected:
The above is a typical way to use protocol in iOS app.