我需要在Swift 3中使用可靠的StopWatch

时间:2017-09-12 08:02:51

标签: swift timer

我在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开始。这段代码有什么问题?

1 个答案:

答案 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")
    }
}