Swift 3 次精确定时器重复 (iOS 9)
Swift 3 precise Timer repeating (iOS 9)
我有一个精确的计时器,需要每 40 毫秒更新一次(尽可能精确)。在 iOS10 上很好(我使用新的 scheduleRepeating
方法)但是在 iOS9 上我需要使用旧方法 (scheduledTimer
) 并且它非常滞后(有时 24ms,有时 72...),所以我的硬件界面和视觉效果和滞后。
有什么建议吗?
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")
}
来自关于 NSTimer
的 Apple 文档:
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.
如果您想要一个非常精确的计时器,您可以检查 Apple Tech Note 的实现并适应 Swift 或使用 CADisplayLink
进行显示更新。
我建议使用 NSThread
并在内部循环而不是计时器。它更复杂,但是,恕我直言,它有更多的设置和灵活的行为
我有一个精确的计时器,需要每 40 毫秒更新一次(尽可能精确)。在 iOS10 上很好(我使用新的 scheduleRepeating
方法)但是在 iOS9 上我需要使用旧方法 (scheduledTimer
) 并且它非常滞后(有时 24ms,有时 72...),所以我的硬件界面和视觉效果和滞后。
有什么建议吗?
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")
}
来自关于 NSTimer
的 Apple 文档:
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.
如果您想要一个非常精确的计时器,您可以检查 Apple Tech Note 的实现并适应 Swift 或使用 CADisplayLink
进行显示更新。
我建议使用 NSThread
并在内部循环而不是计时器。它更复杂,但是,恕我直言,它有更多的设置和灵活的行为