-2

I am trying to implement a stopwatch into my app, but I've noticed that it actually runs slower than it should. Here is the code:

timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(display), userInfo: nil, repeats: true)

func stringFromTimeInterval(interval: TimeInterval) -> NSString {
    let ti = Int(interval)
    let minutes = ti / 6000
    let seconds = ti / 100
    let ms = ti % 100
    return NSString(format: "%0.2d:%0.2d.%0.2d",minutes,seconds,ms)
}

@objc func display() {
    interval += 1
    lapInterval += 1
    timeLabel.text = stringFromTimeInterval(interval: TimeInterval(interval)) as String
    lapLabel.text = stringFromTimeInterval(interval: TimeInterval(lapInterval)) as String
}

Hopefully I've included enough information. Thanks in advance!

Jack Terry
  • 23
  • 3
  • 1
    Do you _really_ need to run that fast? I stronly doubt it, but if so, use CADisplayLink instead. Please search; this has been discussed _many_ times before. – matt Mar 12 '18 at 19:55

1 Answers1

1

Don't try to run a timer that fires every hundredth of a second and then count the number of times it fires. Timers are not exact. Their resolution is more like 50-100 milliseconds (0.05 to 0.1 seconds), and since a timer fires on the main thread, it depends on your code servicing the event loop frequently. If you get into a time-consuming block of code and don't return, the timer doesn't fire.

Plus, the screen refresh on iOS is every 1/60th of a second. There's no point in running a timer more often than that, since you won't be able to display changes any faster.

Run a timer more like every 1/30 of a second, and calculate the elapsed time each time it fires as described below:

To calculate elapsed time, record the time (With Date() or Date().timeIntervalSinceReferenceDate) when you want to begin timing, and then every time you want to update, calculate 'new_date - old_date'. The result will be the number of seconds that have elapsed, and that will be exact and with Double precision.

Duncan C
  • 128,072
  • 22
  • 173
  • 272