问题
This timer isn't firing every second, when I check the log and UI it seems to be firing every 3-4 seconds.
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()
}
Is this just something that is going to happen on the Watch due to lack of capabilities, or is there something wrong in my code?
Here is the log if needed:
0.0396000146865845
3.99404102563858
7.97501903772354
11.9065310359001
EDIT:
And for clarification, what I'm updating every second is the workout timer, so it needs to be updated every second that ticks by.
回答1:
Consider using a WKInterfaceTimer label in place of the label that you are using to show the timing:
A WKInterfaceTimer object is a special type of label that displays a countdown or count-up timer. Use a timer object to configure the amount of time and the appearance of the timer text. When you start the timer, WatchKit updates the displayed text automatically on the user’s Apple Watch without further interactions from your extension. Apple Docs.
WatchOS will then take responsibility for keeping this up-to-date. The OS handles the label for you, but you have to keep track of the elapsed time: you just need to set an NSDate to do that (see example below).
Sample Code.
In your WKInterfaceController subclass:
// 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 }
Comprehensive blog entry: here.
回答2:
If your app is busy doing something else, which blocks or delays the run loop from checking that the fire time has repeatedly passed, the timer will only fire once during that period:
A repeating timer always schedules itself based on the scheduled firing time, as opposed to the actual firing time. For example, if a timer is scheduled to fire at a particular time and every 5 seconds after that, the scheduled firing time will always fall on the original 5 second time intervals, even if the actual firing time gets delayed. If the firing time is delayed so far that it passes one or more of the scheduled firing times, the timer is fired only once for that time period; the timer is then rescheduled, after firing, for the next scheduled firing time in the future.
As an aside, it may be more efficient to update your UI based on a response to a change (e.g., observation), or reaction to an event (e.g., completion handler).
This avoids creating busy work for the app when it's driven to check yet doesn't actually have a UI update to perform, if nothing has changed during the timer interval.
It also prevents multiple changes within the fire interval from being ignored, since a timer-driven pattern would only be displaying the last change in the UI.
来源:https://stackoverflow.com/questions/38937786/timer-not-firing-every-second-on-watchkit