这个计时器每秒都没有点火,当我检查日志和用户界面时,它似乎每3-4秒就会开火一次。
func startTimer() {
print("start timer")
timer = Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(timerDidFire),
userInfo: nil,
repeats: true)
}
func timerDidFire(timer: Timer) {
print("timer")
updateLabels()
}
由于缺乏功能,这是否会在Watch上发生,或者我的代码中有什么问题?
以下是需要的日志:
0.0396000146865845
3.99404102563858
7.97501903772354
11.9065310359001
修改
为了澄清,我每秒更新的是锻炼计时器,因此需要每秒更新一次。
答案 0 :(得分:3)
如果您的应用正忙于执行其他操作,阻止或延迟运行循环检查火灾时间已反复过去,the timer will only fire once during that period:
重复计时器总是根据计划的点火时间来计划自己,而不是实际点火时间。例如,如果计划在特定时间和之后每5秒计时一次计时器,则计划的点火时间将始终落在原始的5秒时间间隔上,即使实际点火时间延迟。 如果射击时间到目前为止它已经过了一个或多个预定的射击时间,那么计时器只会在该时间段内被触发一次; 然后重新安排计时器,在射击之后,为下一个预定的未来发射时间。
另外,根据对更改(例如观察)的响应或对事件的反应(例如,完成处理程序)来更新UI可能更有效。
如果在定时器间隔期间没有任何更改,则可以避免在应用程序被驱动检查但尚未实际执行UI更新时为应用程序创建繁忙的工作。
它还可以防止忽略火灾间隔内的多个更改,因为计时器驱动的模式只会显示UI中的最后一个更改。
答案 1 :(得分:1)
考虑使用WKInterfaceTimer标签代替您用来显示时间的标签:
WKInterfaceTimer对象是一种特殊类型的标签,用于显示 倒计时或计时计时器。使用计时器对象配置 时间量和计时器文本的外观。你几时开始 计时器,WatchKit自动更新显示的文本 用户的Apple Watch没有您的扩展程序的进一步互动。 Apple Docs.
WatchOS将负责保持最新状态。操作系统会为您处理标签,但您必须跟踪已用时间:您只需设置一个NSDate即可(请参阅下面的示例)。
示例代码。
在你的WKInterfaceController子类中:
// Hook up a reference to the timer. @IBOutlet var workoutTimer: WKInterfaceTimer! // Keep track of the time the workout started. var workoutStartTime: NSDate? func startWorkout() { // To count up use 0.0 or less, otherwise the timer counts down. workoutTimer.setDate(NSDate(timeIntervalSinceNow: 0.0)) workoutTimer.start() self.workoutStartTime = NSDate() } func stopWorkout() { workoutTimer.stop() } func workoutSecondsElapsed() -> NSTimeInterval? { // If the timer hasn't been started then return nil guard let startTime = self.workoutStartTime else { return nil } // Time intervals from past dates are negative, so // multiply by -1 to get the elapsed time. return -1.0 * self.startTime.timeIntervalSinceNow }
综合博客文章:here。
答案 2 :(得分:0)
自 2021 年起,(Foundation)Timer 对象支持容差变量(以秒为单位)。设置 timer.tolerance = 0.2,你应该每秒(+/- 0.2 秒)着火。如果您只是更新 GUI,那么确切的时间间隔并不是那么重要,但这应该比不使用容差值更可靠。您需要单独创建计时器,并手动添加到运行队列中,如下所示...(Swift)
import Foundation
// Set up timer to fire every second
let newTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) {timer in
self.timerFired()
}
newTimer.tolerance = 0.2 // For visual updates, 0.2 is close enough
RunLoop.current.add(newTimer, forMode: .common)