I've got a precise timer that needs to be update every 40ms (most precisely than possible). On iOS10 it's good (I use the new scheduleRepeating
method) but on iOS9 I need to use the old way (scheduledTimer
) and it's pretty laggy (sometimes 24ms, sometimes its 72...), so my hardware interface and visual effects and lagging.
Any suggestion?
func launchTimer() {
if #available(iOS 10.0, *) {
startTickTimer()
} else {
let timerQueue = DispatchQueue(label: "my.queue.tickTimer", attributes: .concurrent)
self.swiftTimer = Timer.scheduledTimer(timeInterval: period, target: self, selector: #selector(executeTimer), userInfo: nil, repeats: true)
timerQueue.async {
RunLoop.current.add(self.swiftTimer!, forMode: RunLoopMode.defaultRunLoopMode)
}
}
}
static func startTickTimer() {
let queue = DispatchQueue(label: "my.queue.tickTimer", attributes: .concurrent)
DMXTimer.tickTimer?.cancel()
DMXTimer.tickTimer = DispatchSource.makeTimerSource(queue: queue)
DMXTimer.tickTimer?.scheduleRepeating(deadline: .now(), interval: .milliseconds(40), leeway: .seconds(1))
DMXTimer.tickTimer?.setEventHandler {
executeTimer()
}
DMXTimer.tickTimer?.resume()
}
static func executeTimer() {
print("hello moto")
}
From Apple doc about NSTimer
:
A timer is not a real-time mechanism. If a timer’s firing time occurs during a long run loop callout or while the run loop is in a mode that isn't monitoring the timer, the timer doesn't fire until the next time the run loop checks the timer. Therefore, the actual time at which a timer fires can be significantly later. See also Timer Tolerance.
If you want a very precise timer you can check an implementation from Apple Tech Note and adapt in Swift or use a CADisplayLink
for display updates.