创建 10 分钟计时器。它在多种手机和 iOS 版本上始终适用于我。计时器在 10 分钟时触发。我有一个用户报告说他们的计时器触发时间间隔更长,为 14-18 分钟。什么可能导致这种行为?这是作为基于 iOS UIKit 的常规应用程序的一部分运行的。
出现问题的用户正在 iPhone 14 Pro 上运行 iOS 17.3.1。
对
startLockout
的调用正在主线程上执行。
代码大致如下:
class Manager {
static let shared = Manager()
var timers: Set<Timer> = []
func startLockout() {
let timerLengthInSeconds: Double = 60 * 10
let timer = Timer.scheduledTimer(timeInterval: timerLengthInSeconds,target: self,
selector:#selector(resetLockout),
userInfo: nil,
repeats: false)
timers.insert(timer)
}
@objc func resetLockout(for: Any) {
print("Time: \(Date())")
}
}
虽然“计时器合并”可能会导致一些差异(可以通过使用“严格”gcd 计时器或更改 tolerance
的
Timer
来修复),但这不太可能问题就在这里。
不过,正如 Joakim 所建议的,如果计时器确实在几分钟后触发,则通常不能仅通过计时器合并来解释。更可能的问题是当用户离开应用程序时应用程序被暂停。当用户离开应用程序后应用程序暂停时,在用户重新启动应用程序之前不会触发任何计时器。 (并且您不能让应用程序在后台永久运行;当用户离开应用程序时,执行将被暂停。)
请注意,在使用 Xcode 进行调试时,请勿测试“用户离开应用程序时会发生什么”场景。即使您在连接到调试器时将应用程序保留在设备上,Xcode 也可以人为地使应用程序保持在后台运行。从设备本身启动应用程序时进行测试,而不是运行附加到调试器的应用程序。
假设是这种情况,如果您希望用户即使离开应用程序并且应用程序已暂停也能收到通知,您可以使用 UserNotifications 框架。您的应用程序可能会被暂停,但操作系统会在指定时间向用户发出通知。
因此,假设用户启动了 10 分钟计时器并离开了应用程序。您可以在指定时间安排用户通知,而不是依赖
Timer
(应用程序暂停时不会触发)。这样,即使您的应用程序未激活,操作系统也会在指定时间向用户发出通知。用户可以关闭警报,或者点击它来激活应用程序。但无论如何,他们都会知道 10 分钟已经过去了。
观看 WWDC 2021 视频 发送通信和时间敏感通知。