定时器每次被解雇时都会跳过它的第一秒?

时间:2017-02-06 16:17:30

标签: ios swift timer

我在用户定义的时间运行一个计时器。如果我将其设置为1分钟并将其激活,则计时器将跳过第59秒并在经过一段延迟后从58开始。当我离开视图并返回时,重建计时器并删除经过的时间差,但再次关闭此时间,这样可以使计时器非常不准确!

知道为什么会这样吗?下面是我的定时器代码的核心,如果这还不够,我可以提供任何更广泛的代码:

func createTimer(stopDate: Date) {
    print("CONSTRUCTING A TIMER")
    userDefaults.set(stopDate, forKey: "setStopDate")
    restTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(RestController.updateRestTimer), userInfo: nil, repeats: true)
}

func updateRestTimer() {
    let presentTime = Date()
    let stoppedTime = UserDefaults.standard.object(forKey: "setStopDate") as? Date

    if stoppedTime?.compare(presentTime) == .orderedDescending {
        restRemainingCountdownLabel.text = dateComponentsFormatter.string(from: presentTime, to: stoppedTime!) // this is where that first second is missed
        print(stoppedTime as Any)
    } else {
        self.stopTimer()
        userDefaults.set(nil, forKey: "ViewDidChangeTime")
        self.restRemainingCountdownLabel.text = "Done"
    }
}

let dateComponentsFormatter: DateComponentsFormatter = {
    let _formatter = DateComponentsFormatter()
    _formatter.allowedUnits = [.minute, .second]
    _formatter.unitsStyle = .positional
    _formatter.zeroFormattingBehavior = .pad
    return _formatter
}()

1 个答案:

答案 0 :(得分:2)

首先,您决定停止时间。然后,在很短的时间之后,你计划一个计时器在1秒钟内开火(这比你的停止时间稍微少于59秒)。

在一秒钟之后稍微过了一些时间(计时器不完美,但它们从未提前),你的计时器会启动,稍后你会获取当前时间。此时,肯定小于59秒直到停止时间(所有小错误都在一个方向,向前,所以它们复合)。即使错误平衡,它们也可能无法完美平衡。

好的,所以它在58到59秒之间,直到你的停止时间。好吧,几乎可以肯定超过58秒,保证不到59秒。然后将其交给日期组件格式化程序,并允许分钟和秒数。

日期组件格式化程序不会舍入。 “58以上且不到59”是58.所以打印58。

你可能想要的是舍入,但格式化程序会截断。那没问题;很容易将截断变为舍入:在截断之前加上一半。因为你倒计时,你想从当前时间减去0.5(因为两个底片为正;或者你可以计算差值然后加0.5,但这更容易):

let presentTime = Date().addingTimeInterval(-0.5)