0

in my application,I have implemented NSTimer to count time.I have swipe detection and when the user swipes on the screen,animation runs continuously.my question is when I swipe on the screen(left/right continuously) NSTimer slows down. can anybody tell me how to solve this problem?

//code

    gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/100
                                                          target:self
                                                        selector:@selector(updateGameTimer)
                                                        userInfo:nil
                                                        repeats:YES];

    -(void)updateGameTimer
    {
        counter++;
        tick++;
        if(tick==100){
            tick = 0;
            seconds += 1;
        }
        if(counter==100){
            counter = 0;
        }
        timerLabel.text = [NSString stringWithFormat:@"%i.%02d",seconds,counter];
    } 


//swipe detection

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesMoved:touches withEvent:event];

    UITouch *touch = [touches anyObject];
    //CGPoint curPt = [touch locationInView:self.view];    
    CGPoint newLocation = [touch locationInView:self.view];
    CGPoint oldLocation = [touch previousLocationInView:self.view];
    gameView.multipleTouchEnabled = true;

    if(newLocation.x-oldLocation.x>0){
        swipe_direction = 1;
        //NSLog(@"left");
    }
    else{
        swipe_direction = 2;
        //NSLog(@"right");

    }

    if(swipe_direction==1){
        //animate images
        //play sound effect
    }
    else if(swipe_direction==2){
       //animate images
       //play sound effect
    }

}

2 Answers2

5

From the NSTimer documentation...

A timer is not a real-time mechanism; it fires only when one of the run loop modes to which the timer has been added is running and able to check if the timer’s firing time has passed. Because of the various input sources a typical run loop manages, the effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds. If a timer’s firing time occurs during a long callout or while the run loop is in a mode that is not monitoring the timer, the timer does not fire until the next time the run loop checks the timer. Therefore, the actual time at which the timer fires potentially can be a significant period of time after the scheduled firing time.

Your timer resolution is 10 milliseconds, so if the run loop doesn't not complete quickly enough (under 10 milliseconds), you'll start to notice a lag between real-time, and your counters.

If you are implementing a game, devs will generally try to disassociate from the CPU or clock speed.

Take a look at this answer

or take a look at how a framework like cocos2d implements its own scheduler.

Community
  • 1
  • 1
Eoin
  • 767
  • 3
  • 12
0

It's hard to tell from the description what "slows down" means. Is it just not quite keeping up with the real clock due to processing load, or is it actually stopping briefly?

In some situations like this, the problem is actually that while certain UI processes are occurring, like touch event handling, or scrolling, you are in a different run loop mode. A default NSTimer instance will actually not be fired in this mode, unless you explicitly tell iOS to do so.

See this other answer here.

It may be as simple as adding your timer to the list of timers for the proper run loop modes:

gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/100
                                             target:self
                                           selector:@selector(updateGameTimer)
                                            serInfo:nil
                                            repeats:YES];

[[NSRunLoop currentRunLoop] addTimer: gameTimer forMode: NSRunLoopCommonModes];

It's a simple one line change to see if this fixes your problem. Much easier than redesigning your entire ticking mechanism. Give it a shot!

Community
  • 1
  • 1
Nate
  • 31,017
  • 13
  • 83
  • 207
  • I tried.unfortunately still stops the timer when I swipe on screen. – machinetosh12 Jul 23 '12 at 08:39
  • @machinetosh12, unfortunately, that probably means that the amount of work you are doing in `touchesMoved:withEvent:` is as much as the main thread can complete, given the CPU resources allocated to it. Worth a try, though! – Nate Jul 23 '12 at 08:43
  • @machinetosh12, according to [this answer](http://stackoverflow.com/a/1352642/119114), 1/100th of a second might just be too fast. I'm not sure if the 1/45th of a second rpetrich quotes there is an old number (the post was made a long time ago), or if it's still the same number, because of fundamental UI design limits that have been coded to the properties of the human eye (which don't change with new iPhone hardware!) ... people really can't detect changes at 100Hz, so you might consider running your timer more slowly. – Nate Jul 23 '12 at 08:48
  • thank you.gave up..100Hz is too fast so I changed value to 1/10.now it's works fine. – machinetosh12 Jul 24 '12 at 02:23
  • @machinetosh12, the human eye only sees something like 13Hz information, or slower, and so (maybe because of something like the Nyquist theorem) UIs often update at about twice that rate. But, I would guess it still looks fine at 10Hz. – Nate Jul 24 '12 at 12:41