Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IOS application - define protocol in separate file

I have defined a protocol in a separate file (myProtocol.h). Here is the code for it:

#import <Foundation/Foundation.h>

@protocol myProtocol <NSObject>
    -(void) loadDataComplete;
@end

Now I want to call this method so I have done the following code:

firstViewController.h:

#import "myProtocol.h"

@interface firstViewController : UIViewController{
    id <myProtocol> delegate;
}
@property (retain) id delegate;
-(void) mymethod;

firstViewController.m

@implementation firstViewController
@synthesize delegate;

- (void)viewDidLoad {
    [self mymethod];
}

-(void) mymethod {
    //some code here...
    [delegate loadDataComplete];
}

I have another file where the protocol is also utilized:

secondViewController.h:

#import "myProtocol.h"
@interface secondViewController : UIViewController<myProtocol>{
}

secondViewController.m:

-(void) loadDataComplete{
    NSLog(@"loadDataComplete called");
}

but my secondViewController is not calling the protocol methad. Why is it so? Any suggestion will be appreciated.

like image 224
Viral Narshana Avatar asked Jul 14 '12 10:07

Viral Narshana


1 Answers

First, as @Abizern suggested, try to reformat your code a little bit. Use capital letter for classes. Said this here the solution for your answer.

This is the protocol. I would name it like FirstViewControllerDelegate since the class that implements the object is a delegate for FirstViewController.

#import <Foundation/Foundation.h>

@protocol MyProtocol <NSObject>

- (void)doSomething;

@end

This is SecondViewController.

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

@interface SecondViewController : UIViewController <MyProtocol>

@end

@implementation SecondViewController

// other code here...

- (void)doSomething
{
    NSLog(@"Hello FirstViewController");
}

@end

This is FirstViewController.

#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController

// it coud be better to declare these properties within a class extension but for the sake of simplicity you could leave here
// the important thing is to not declare the delegate prop with a strong/retain property but with a weak/assign one, otherwise you can create cycle
@property (nonatomic, strong) SecondViewController* childController;
@property (nonatomic, weak) id<MyProtocol> delegate;

@end

@implementation FirstViewController

// other code here...

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.childController = [[SecondViewController alloc] init];
    self.delegate = self.childController; // here the central point

    // be sure your delegate (SecondViewController) responds to doSomething method
    if(![self.delegate respondsToSelector:@selector(doSomething)]) {

        NSLog(@"delegate cannot respond");
    } else {

        NSLog(@"delegate can respond");
        [self.delegate doSomething];
    }    
}

@end

For the sake of completeness, be sure to understand the delegate pattern means. Apple doc is your friend. You could take a look at the-basics-of-protocols-and-delegates to have a basic intro on the argument. Furthermore, SO search allows you to find a lot of answers on the topic.

Hope that helps.

like image 77
Lorenzo B Avatar answered Oct 12 '22 22:10

Lorenzo B