我需要 Swift 3 中可靠的 StopWatch。我根据在 SO 上找到的另一个示例想出了这个 ...
import Foundation
class StopWatch {
public private(set) var seconds:Double = 0
public var milliseconds: Double { return seconds * 1000 }
private weak var timer:Timer?
private var startTime:Double = 0
public private(set) var started = false
public func start() {
if started { return }
started = true
startTime = Date().timeIntervalSinceReferenceDate
timer = Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) {
timer in
if !self.started { return }
self.seconds = Date().timeIntervalSinceReferenceDate - self.startTime
print("Seconds: \(self.seconds)")
}
print("Started")
}
public func stop() {
if !started { return }
timer?.invalidate()
started = false
print("Stopped")
}
}
但这似乎并不可靠。获取秒数通常保持在 0,或者在其他情况下,当访问秒数时它们不是从 0 开始。这段代码有什么问题?
最佳答案
这很可能是线程问题。如果涉及 UI,则必须确保与 UI 相关的代码在主线程上运行。
变量started
是多余的。检查计时器是否为 nil
也是如此。
此代码添加了一个 DispatchQueue.main
block 。将您用于更新 UI 的代码放入此 block
class StopWatch {
public private(set) var seconds:Double = 0
public var milliseconds: Double { return seconds * 1000 }
private weak var timer : Timer?
private var startTime : Double = 0
private var timerIsRunning : Bool { return timer != nil }
public func start() {
if timerIsRunning { return }
startTime = Date().timeIntervalSinceReferenceDate
timer = Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { timer in
self.seconds = Date().timeIntervalSinceReferenceDate - self.startTime
print("Seconds: \(self.seconds)")
DispatchQueue.main.async {
// do something on the main thread
}
}
print("Started")
}
public func stop() {
if !timerIsRunning { return }
timer!.invalidate()
timer = nil
print("Stopped")
}
}
关于swift - 我需要一个可靠的 Swift 3 秒表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46171055/