0

Problem is to stop NSTimer, for some reason [Timer invalidate] just not working...

Maybe my eyes are full of soap, but can't understand the reason why the timer didn't stop at 0, but go reverse counting -1, -2, -3 and so on...(((

I'm using epoch numbers as destination date. One more thing - my button "IBAction stop" with [Timer invalidate] works just fine - when i push it in simulator timer stops...

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];


Timer = [NSTimer  scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabel) userInfo:nil repeats:YES];

}

- (IBAction) start {

Timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabel) userInfo:nil repeats:YES];


}
- (IBAction) stop {

[Timer invalidate];
Timer = nil;

}

-(void)updateLabel {

NSCalendar *calender = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
int units = NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *components = [calender components:units fromDate:[NSDate date] toDate:destinationDate options:0];
[dateLabel setText:[NSString stringWithFormat:@"%d%c  %d%c  %d%c  %d%c", [components day], 'd', [components hour], 'h', [components minute], 'm', [components second], 's']];

destinationDate = [NSDate dateWithTimeIntervalSince1970:1355299710];

if (!destinationDate) {

    [Timer invalidate];
    Timer = nil;
}
}
Techie
  • 44,706
  • 42
  • 157
  • 243
Alex Kort
  • 23
  • 1
  • 5
  • if (!destinationDate) { --> is always true because it only checks if the var is instantiated so if never invalidated the timer there. aka you never reach the inside of ur instatement. You should redo your ifstatement and ull be fine. – Totumus Maximus Dec 12 '12 at 08:38
  • ok, i feel there is something with if statement, but i tried many ways - not just destination date, but "dateLabel.text <=0" still no good... – Alex Kort Dec 12 '12 at 14:52
  • dateLabel.text is a NSString and u cant compare that to an int like 0. You will have to add dateLabel.text.lenght in that case. Your ifstatements are not complete. – Totumus Maximus Dec 12 '12 at 16:06

1 Answers1

0

As Totumus pointed out, your if statement condition !destinationDate always evaluates to false, so your updateLabel method never invalidates your timer.

You have another bug too:

You're creating a timer in viewDidLoad and storing a reference to it in your Timer instance variable.

Then you're creating another timer in start and storing a reference to it in your Timer instance variable, overwriting the reference to the timer you created in viewDidLoad without invalidating that older timer.

So now you have two timers running, but you don't have a reference to the older timer, so you can never invalidate it.

Note that the run loop has a strong reference to a scheduled (running) timer, so even if you remove all of your strong references to it, the timer keeps running. That's why the invalidate message exists: to tell the run loop to remove its strong reference to the timer.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • he didnt say he pressed the button. also his stop button works fine implicating the invalidate isnt the problem. Nor is the timer – Totumus Maximus Dec 12 '12 at 08:39
  • @TotumusMaximus true, but the start method is dangerous then :D I always call [timer invalidate] before refreshing it and I think he should – Daij-Djan Dec 12 '12 at 08:41
  • @TotumusMaximus Your points are valid. However, the `start` action is broken unless he has code to prevent it from being called when there's a running timer. – rob mayoff Dec 12 '12 at 08:43
  • yeah ofc it is an error to do it that way. However that wasn't his question ;) – Totumus Maximus Dec 12 '12 at 08:44