2017-02-06 2 views
0

Я запускаю таймер в определенное пользователем время. Если я установил это на 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 
}() 
+3

Таймеры не являются о «точности». – matt

ответ

2

Во-первых, вы сами решаете, когда время остановки. Затем, через небольшой промежуток времени, вы планируете запуск таймера в течение 1 секунды (что будет чуть меньше 59 секунд от вашего времени остановки).

В какой-то момент через несколько секунд (таймеры не идеальны, но они никогда не бывают ранними), ваш таймер срабатывает, и немного после этого вы выбираете текущее время. На данный момент это определенно менее чем за 59 секунд до вашего времени остановки (все небольшие ошибки в одном направлении, вперед, так что они сложны). Даже если ошибки будут сбалансированы, они, вероятно, не будут идеально сбалансированы.

ОК, так что это где-то между 58 и 59 секундами до вашего времени остановки. Ну, почти наверняка более 58 секунд, и гарантировано менее 59 секунд. Затем вы передаете его формату компонентов даты с указанием минут и секунд.

Компонент компонентов даты не круглый. «Более 58 и меньше 59» - 58. Таким образом, он печатает 58.

Возможно, вы хотите округлить, но форматер усекает. Это не проблема; легко превратить усечение в округление: просто добавьте половину перед усечением. Потому что вы отсчитывать, вы хотите вычесть 0.5 из текущего времени (потому что два негативы сделать положительным, или вы могли бы вычислить разницу, а затем добавить 0,5, но это проще):

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

Блестящая благодарность за краткий и точный ответ, предлагаемое решение разрешило проблему! – jwarris91