我在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开始。这段代码有什么问题?
答案 0 :(得分:0)
这很可能是一个线程问题。如果涉及UI,则必须确保UI相关代码在主线程上运行。
变量started
是多余的。检查nil
的计时器是否也一样。
此代码添加了DispatchQueue.main
块。将您的代码更新为此块
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")
}
}