0

Just when I thought I had my head around how delegates work, it seems I am missing something.

I've setup a delegate like so:

ViewControllerA.h

@protocol LoginDelegate <NSObject>

-(void)userLoginSuccessful;

@end
@interface BBLoginViewController : BBBaseViewController
@property (weak, nonatomic) id <LoginDelegate> delegate; 

@end

ViewControllerA.m

-(void)someMethod 
{
    if ([self.delegate respondsToSelector:@selector(userLoginSuccessful)]){
                [self.delegate userLoginSuccessful];
            }
        [self dismissViewControllerAnimated:YES completion:nil];

}

ViewControllerB.m

    #import "ViewControllerA.h"

    @interface ViewControllerB () <UITableViewDataSource, UITableViewDelegate, LoginDelegate>


    -(void)viewWillAppear:(BOOL)animated
    {

        ViewControllerA *loginViewController = [[ViewControllerA alloc]init];
        loginViewController.delegate = self;

    }

#pragma mark - Login Delegate

-(void) userLoginSuccessful
{
  NSLog (@"Delegate fired!");
}

After all this my delegate method does not fire. What am I doing wrong? I looked at this SO answer and when checking the delegate is not nil - it is not. Its set to ViewControllerB.

halfer
  • 19,824
  • 17
  • 99
  • 186
Robert J. Clegg
  • 7,231
  • 9
  • 47
  • 99
  • 2
    Check your delegate method. you have defined this protocol method `userLoginSuccessful` and you are calling `-(void)expanItemImage:(UITapGestureRecognizer *)tap` – ChintaN -Maddy- Ramani May 20 '14 at 07:42
  • And you do not need to check if your delegate responds to the protocol selector since you defined it correctly as a type conforming to the LoginDelegate protocol. – giorashc May 20 '14 at 07:42
  • Copy and paste error - updated the question. Sorry gents. I removed the IF statement checking if the selector responds to the delegate and it still doesn't get called – Robert J. Clegg May 20 '14 at 07:44
  • Do you reach the line [self.delegate userLoginSuccessful]; ? – streem May 20 '14 at 07:45
  • I reach the if statement. Which never executes. Removing the statement and just calling [self.delegate userLoginSuccessful]; doesn't work either. – Robert J. Clegg May 20 '14 at 07:46
  • @giorashc why? Its always better to check your delegate respond to the corresponding selector. You can avoid a crash some times. – Anil Varghese May 20 '14 at 07:48
  • It's probably not the same instance of ViewControllerA. How do you add ViewControllerA to ViewControllerB ? – streem May 20 '14 at 07:49
  • @Anil true for optional methods declared in a protocol but in his case he has only one required method. – giorashc May 20 '14 at 07:50
  • Its better if you follow some conventions, will help you future :) – Anil Varghese May 20 '14 at 07:52
  • to be on the safe side I totally agree – giorashc May 21 '14 at 07:53
  • I've always used the if statement to check the selector as I have had crashes before due to that very reason. Now I just implement it and know 100% I will never get a crash because it was sent to a class that has no idea what its about. – Robert J. Clegg May 21 '14 at 08:53
  • @Tander this can go either way since now you will not know you have a problem espcially if the selector does not preform something that is visible – giorashc May 21 '14 at 11:17

2 Answers2

3

This code:

-(void)viewWillAppear:(BOOL)animated
{

    ViewControllerA *loginViewController = [[ViewControllerA alloc]init];
    loginViewController.delegate = self;

}

Will create a ViewControllerA object and then (almost) immediately destroy it and is not what you intended.

You probably want to be setting the delegate in the prepareForSegue: method anyway...

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
2

Set the delgate before presenting ViewControllerB. The below code is not required anymore

-(void)viewWillAppear:(BOOL)animated
  {
     ViewControllerA *loginViewController = [[ViewControllerA alloc]init];
     loginViewController.delegate = self;

  }

Dont do like that. It will give you unexpected results. Remember always set the delegate before moving to the next view. If you are presenting modally just before presentViewController of if you are using segue in prepareForSegue

Anil Varghese
  • 42,757
  • 9
  • 93
  • 110