A timer is a good way to periodically update your user interface, but do not use it to track time. NSTimer can drift , and any small errors can accumulate if you use a timer to accumulate seconds.
Instead, use NSTimer to run a method that updates your user interface, but get real-time using NSDate. NSDate will give you resolution in milliseconds; if you’re really better, consider using the clock synchronization features . Thus, using NSDate, your code might look something like this:
- (IBAction)startStopwatch:(id)sender { self.startTime = [NSDate date]; self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(tick:) userInfo:repeats:YES]; } - (void)tick:(NSTimer*)theTimer { self.elapsedTime = [self.startTime timeIntervalSinceNow]; [self updateDisplay]; } - (IBAction)stopStopwatch:(id)sender { [self.timer invalidate]; self.timer = nil; self.elapsedTime = [self.startTime timeIntervalSinceNow]; [self updateDisplay]; }
Your code may be a little more complicated if you allow restarting, etc., but it is important here that you do not use NSTimer to measure the total elapsed time.
You will find additional useful information in this SO thread .
Caleb
source share