views:

46

answers:

5

I'd like to create an NSTimer that repeats twice then stops and invalidates itself. I'd rather not use a loop if that's possible. Any thoughts on how I could do this?

+1  A: 

Create a static int inside your timer delegate function that is initialized to 0.
Increment it each time the delegate is called.
When the counter reaches the value you wish invalidate the timer.

KevinDTimm
+1  A: 

This is something your timer's target should handle, not something the timer itself should handle. You can either install a repeating timer and have the target invalidate it the second time it fires, or you can install a one-shot timer, reinstall it after the first time it fires, and then not set it up again the second time.

Jeremy W. Sherman
A: 

One solution might look similar to this.

Launching the timer

[NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(timerMethod:) userInfo:nil repeats:YES];

Handling the timer and repetitions

int repetitions = 2;  //EDIT: remove static declaration (see below)

- (void)timerMethod:(NSTimer*)theTimer{
    NSLog(@"Timer fired");
    repetitions--;

    if(repetitions == 0){
        [theTimer invalidate];
        NSLog(@"Timer stopped");
    }
}

EDIT: I removed the static modifier above to make a more generic example. The original intent of the static was to persist the timer across objects of similar type, a request that the OP did not make.

Error 454
Downvoted because global variables are a recipe for disaster.
St3fan
especially when the static modifier makes them moot.
KevinDTimm
This was meant to be a static inside some class definition.
Error 454
Thanks everybody!! Error 454 I tried your method and it seems to work just fine thanks!!!
cgossain
A: 

Basically, you need a state machine state variable that can be accessed both from the routine that initializes the timer, and from the timer's target.

Set the state variable to allow the first call to the timer task to restart the timer, but in that call also set that state variable so that subsequent calls do not restart.

Note that this kind of state variable can be used for any number of timer task repetitions, by simply decrementing it.

State machines are pretty much how all (synchronous) digital chips and logic works.

hotpaw2
A: 

I very much disagree with the Jeremy that this is something that the target should handle. In fact I disagree so much that I have created my own Timer class, based on NSTimer, that you can configure in detail.

- (void) doSomething: (Timer*) timer
{
    NSLog(@"This is iteration %d", timer.currentIteration);
}

- (void) startDoingSomething
{
    Timer* timer = [Timer new];
    timer.interval = 5.0; // Fire every 5 seconds
    timer.delay = 2.5;    // Start firing after 2.5 seconds
    timer.iterations = 3; // Only fire three times
    timer.target = self;
    timer.selector = @selector(doSomething:);
    [timer schedule];

    // Don't forget to release timer somewhere - the above is just an example
}

See http://github.com/st3fan/ios-utils

St3fan