Search code examples
objective-ciosloopsnstimer

Set timer loop for a fixed time


I am creating a game. When the user finished the game I am showing him the score. To make it interactive I am counting the score from 0 to the score.

Now since the user can earn 10 points or 100,000 I don't want hime to wait to long so I want that the total time will be fixed no matter what is the score.

So I did that but it seems that the timer interval is not influenced by the interval value.

Where is the problem ?

///score timer
-(void)startScoreCountTimer:(NSNumber*)score{

finishedGameFinalScore = [score integerValue];
CGFloat finishedGameFinalScoreAsFloat = [score floatValue];
CGFloat interval = 2.0f/finishedGameFinalScoreAsFloat;
NSLog(@"interval = %f",interval);

NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
timer = [[NSTimer alloc] initWithFireDate:fireDate
                                 interval:interval
                                   target:self
                                 selector:@selector(timerMethod:)
                                 userInfo:nil
                                  repeats:YES];

NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
}

- (void)timerMethod:(NSTimer*)theTimer{

scoreCount++;
finalScoreLabel.text = [NSString stringWithFormat:@"%i",scoreCount];

   if (scoreCount == finishedGameFinalScore ||finishedGameFinalScore ==0) {
    [theTimer invalidate];
    scoreCount=0;
    [self updateMedalsBoard];
   }
}

Solution

  • NSTimers aren't guaranteed to fire exactly every X seconds (or milliseconds, or in your case, microseconds). You can only know for sure that they'll fire sometime after X seconds (etc.) have passed. In your case, it looks like you're incrementing the score just one point at a time, and that takes up time on the main thread before the NSTimer has an opportunity to fire again, which slows down the whole process.

    A better approach might be to simply have the timer repeat every, say, 0.1 seconds for 2 seconds. In each invocation of timerMethod:, add 1/20th of the total score until you reach the final total in the last iteration. You can, of course play around with the exact intervals to find something that looks good.