4
[NSTimer scheduledTimerWithTimeInterval: target: selector: userInfo: repeats:NO];

When repeats: is set to NO, do I need to invalidate the timer inside the specified selector?

Thank you

Edit

Another question, if it self invalidates,

How do you properly cancel a such timer?
Since invalidating already-invalidated timer would crash I assume?

maintain a pointer to the timer and set it to nil inside the selector that will get fired?

Robin
  • 10,011
  • 5
  • 49
  • 75
eugene
  • 39,839
  • 68
  • 255
  • 489

5 Answers5

7

No, the timer will invalidate itself

Kai
  • 541
  • 1
  • 3
  • 11
  • thank you. then http://stackoverflow.com/questions/1429571/how-to-stop-nstimer-event this code should actually somewhere retain timer to properly cancel timer I think? since invalidating auto-invalidated timer will crash? – eugene Mar 04 '11 at 08:28
  • if it is a non repeating timer (repeats:NO) there is no need to cancel the timer. The timer invalidates itself and gets released. For a repeating timer you need to maintain a reference to the timer to explicitly call invalidate. – Kai Mar 04 '11 at 08:44
1

@Eugene if you are using

[NSTimer scheduledTimerWithTimeInterval: target: selector: userInfo: repeats:YES];

then in the selector method you need to give a function like this one

- (void)timerFireMethod:(NSTimer*)theTimer

so when you want to invalidate it you can have a condition like this one

if(workDone == YES)
{
   [theTimer invalidate];
}

But if you are using NO in the repeat option then the timer will invalidate itself.

Robin
  • 10,011
  • 5
  • 49
  • 75
1

You can maintain flag to save whether the timer has been fired or not.

eg.

    BOOL gameOver = NO;
    NSTimer * gameOverTimer;


-(void)startGame
{

     gameOverTimer =    [NSTimer scheduledTimerWithTimeInterval:600 target:self selector:@selector(stopLevel:) userInfo:nil repeats:NO]; 
     // your code
}

-(void)stopLevel:(id)sender
{
     gameOver = YES;
     // your code
}

-(void)levelFinishedSuccesfully
{
     // this method will get called if user finishes the level before your timer ends/stops the level. So the timer is valid and we need to invalidate it
     if(!gameOver)
     {
          [gameOverTimer invalidate];
          gameOverTimer = nil;
     }    
      // your code
}

Hope this helps.

Vaibhav Tekam
  • 2,344
  • 3
  • 18
  • 27
0

you are missing to add the timer source to your runloop

addTimer:forMode:

vp_gold
  • 532
  • 4
  • 12
0

If repeats is YES, the timer will repeatedly reschedule itself until invalidated. If NO, the timer will be invalidated after it fires.

visakh7
  • 26,380
  • 8
  • 55
  • 69