SwiftUI:使用计时器时,每次平均执行会保持不变吗?

SwiftUI: When using a timer, will the average execution per time stay constant?

我目前正在开发一个内置计时器元素的应用程序。因此,如果用户选择 30 分钟,应用程序将显示剩余时间 -- 29:59、一秒后 29:58、29:57 等。计时器可以在几个小时内激活一个时间。经过一番研究,我发现有人说计时器不那么准确,不应该用于“高精度计时”?所以我不确定这会带来什么。计时器在一定时间内执行的平均速率在几个小时后是否仍保持不变?例如,如果我设置一个计时器每秒将一个整数加 1,那么在 4 小时后整数值是否为 14,400(前后大约 +/-10)(因为 4 小时内有 14,400 秒)?

import SwiftUI

struct ContentView: View {
    @State var timeElapsed = 0
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    var body: some View {
        VStack{
            Text(String(timeElapsed)) //Would this display 14400 after 4 hours?
        }
        .onReceive(timer) { _ in
            timeElapsed += 1
        }
    }
}

没有。没有保证每秒都会调用它。特别是,您的应用程序可能会进入后台,并且不会调用此计时器。 (超过 4 小时,这几乎是肯定的。)计时器不会累积未接来电。他们只是跳过它们。

实现计时器的方法是从当前时间减去开始时间,而不是尝试累加秒数。你想要更像这样的东西(未经测试):

struct ContentView: View {
    @State var timeElapsed = 0
    @State var startTime = Date()
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    var body: some View {
        VStack{
            Text(String(timeElapsed)) //Would this display 14400 after 4 hours?
        }
        .onReceive(timer) { _ in
            timeElapsed = Int(-startTime.timeIntervalSinceNow)
        }
        .onAppear { startTime = Date() }
    }
}

还有一个iOS15的方法

import SwiftUI

@available(iOS 15.0, *)
struct NewTimerView: View {
    let startDate: Date = Date()
    var body: some View {
        //A view that updates according to a schedule that you provide
        TimelineView(.periodic(from: startDate, by: 1), content: {context in
            Text((-startDate.timeIntervalSinceNow.rounded()).description)
        })
    }
}

https://developer.apple.com/documentation/swiftui/timelineview

来自 WWDC 的锻炼应用程序代码对其进行了跟踪 https://developer.apple.com/wwdc21/10009