update display every second - more precisely

Hello all,


I am relatively new to iOS programming (been doing it about a month). I am developing an app (game) for which I need to display a countdown timer. I have used the Timer class, creating a timer that repeats every 1.0 second in my viewDidAppear method of my view controller. When it fires, the selector decrements an Int representing time left and updates the label that shows time with the value of that Int. It also calls setNeedsDisplay on the label. There is really not anything else going on in this view yet other than that, but for some reason the countdown is very jerky; sometimes it even skips seconds.


I have read that the Timer is not exact, but I wouldn't expect noticeable differences in firing times 1 second apart. The fact that sometimes seconds are skipped also indicates that sometimes the view is not updated when the timer fires. I have also read that setNeedsDisplay is the most appropriate way to get drawing done as soon as possible. It seems to be happening unacceptably slowly. I have just been working on the simulator for now; is this just a problem with running on the simulator, or am I not using the right classes/methods, or what?


Thanks for your time.

Replies

>There is really not anything else going on


Debugging is an experimental science not a theoretical science. Make absolutely certain that nothing else is going on that would block the thread; absolutely certain. Then reintroduce each component of the code and you may discover something you thought was benign is not.


Although not advised, I often use this rather than a timer:

-(void)delayCode{
        // need this in case you call this method more than once:
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(delayCode) object:nil];
        // this will call back in one second:
        [self performSelector:@selector(delayCode) withObject:nil afterDelay:1.0f];
        //enter code that gets executed every second:
        //     code here
}

//be sure to execute this before leaving the class:
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(delayCode) object:nil];

Fortunately for me, I wasn't lying when I said there was very little going on in this view other than what I mentioned. After a bit of futzing around, I was able to determine that viewDidAppear got called twice, and thus two timers were running and calling the selector. Initializing the timer only if it was currently nil solved the problem. Thanks for your help.