0

I'm trying to implement delegation. In the .h file of a custom class , I do this

#import <UIKit/UIKit.h>

@class Timer;

@protocol TimerDelegate

-(void)myClassDelegateMethod:(Timer *)timer;

@end

typedef void(^MyCustomBlock)(void);

@interface Timer : UILabel
@property (nonatomic, weak) id <TimerDelegate> delegate;

In the .m file I synthesize the delegate and also called the delegate method, checking to see first if the delegate implements the method

@synthesize delegate;

-(void)countdownTime:(NSTimer *)timer 
{
    NSLog(@"countdownTime called");
    ....
    [self.delegate myClassDelegateMethod:self];
    if (self.delegate != nil && [self.delegate respondsToSelector:@selector(myClassDelegateMethod:)]) {
    [self.delegate performSelector:@selector(myClassDelegateMethod:)];
    } else {
    NSLog(@"Delegate doesn't implement myClassDelegateMethod");
    }

when I run my code, I'm told the delegate doesn't implement the method. Here's how I implement it In the viewController, I declare that it conforms to the protocol

@interface scViewController : UIViewController  <TimerDelegate>

And then in the .m file of the viewController, I implement the delegate's method

- (void) myClassDelegateMethod:(Timer *) sender {
    NSLog(@"Delegates are great!");
}

Can you explain how I've failed to implement the delegate method properly?

Update, in the viewController, I have a method that creates timer instances

-(Timer *)timer
{
    _timer = [[Timer alloc] init];


    return _timer;
}

In viewDidLoad, I do this

 self.timer.delegate = self;
BrainLikeADullPencil
  • 11,313
  • 24
  • 78
  • 134
  • Do you ever do `timer.delegate = scViewController`? i.e. do you ever assign a delegate to a `Timer` instance? – Rich Apr 26 '14 at 17:46
  • @Rich thanks, yes, I do this in viewDidLoad of the vc `self.timer.delegate = self;` – BrainLikeADullPencil Apr 26 '14 at 17:47
  • Also you declare `myClassDelegateMethod:` with an argument but `performSelector:` without one... Does the code crash, or does it log out "_Delegate doesn't implement myClassDelegateMethod_"? – Rich Apr 26 '14 at 17:48
  • @rich noted, however if you look at my code (updated), I also call it this way with an argument `[self.delegate myClassDelegateMethod:self];` and the log statement in the implementation in delegate never gets logged. There's no crash. – BrainLikeADullPencil Apr 26 '14 at 17:51
  • Yeah, just noticed your edit. Have you checked what `self.delegate` is? Is it `nil`? – Rich Apr 26 '14 at 17:52
  • @Rich, yes, I just logged ` NSLog(@"self delegate %@", self.delegate);` in the countdownTime method and it's (null) – BrainLikeADullPencil Apr 26 '14 at 17:55
  • 2
    Show the code were you create the `Timer` instance and set its `delegate` property. – rmaddy Apr 26 '14 at 17:55
  • @BrainLikeADullPencil how is the `timer` property declared? – Rich Apr 26 '14 at 18:01
  • seems you're doing `self.timer.delegate = self;` too soon. i.e. before `_timer = [[Timer alloc] init];` – staticVoidMan Apr 26 '14 at 18:01
  • @staticVoidMan `self.timer` would call the `timer` getter and create a new instance... – Rich Apr 26 '14 at 18:03
  • @Rich : huh... so you're saying that if i `@property` and `@synthesize` `ABC *abc;` and simply do `self.abc;` that will be equivalent to `abc = [[ABC alloc] init];`? nah... i am sure the delegate was being set prematurely – staticVoidMan Apr 26 '14 at 18:19
  • @staticVoidMan as he's written the above question, yes it would create a new instance each time. – Rich Apr 26 '14 at 18:21
  • @Rich : oh ok, right... _didn't think much about `-(Timer *)timer`_ – staticVoidMan Apr 26 '14 at 18:23

1 Answers1

3

Your timer method is a problem. It should be:

-(Timer *)timer
{
    if (!_timer) {
        _timer = [[Timer alloc] init];
    }

    return _timer;
}

As you have it, every time you do self.timer you were creating a new timer so the delegate was only applied to one of the many instances.

rmaddy
  • 314,917
  • 42
  • 532
  • 579