WatchOS中DispatchSourceTimer计时器启停重置功能报错求助
问题分析与解决方案
核心问题原因
- 废弃的Flag参数:Xcode提示的错误源于
.strict标记在新版watchOS SDK中已被弃用,该标记用于严格的计时器精度控制,但当前系统已不再支持。 - 计时器状态管理混乱:原代码未跟踪计时器的运行/暂停状态,导致重复创建计时器、在已取消的计时器上调用
suspend()操作,进而触发崩溃。 - 潜在循环引用:事件处理器中直接使用
self会导致计时器与类实例互相持有,引发内存泄漏。
修复后的完整代码
class WatchTimer: NSObject, ObservableObject { @Published var counterTime: Int = 0 private var timer: DispatchSourceTimer? private var isRunning = false private var isPaused = false private let timerQueue = DispatchQueue(label: "com.app.watchkitapp", qos: .userInteractive) func startTimer() { guard !isRunning else { // 若处于暂停状态,恢复计时 if isPaused { timer?.resume() isPaused = false } return } // 创建计时器(移除废弃的.strict标记) timer = DispatchSource.makeTimerSource(queue: timerQueue) timer?.schedule(deadline: .now(), repeating: 1) timer?.setEventHandler { [weak self] in DispatchQueue.main.async { self?.counterTime += 1 } } timer?.resume() isRunning = true isPaused = false } func stopTimer() { guard isRunning, !isPaused else { return } timer?.suspend() isPaused = true } func resetTimer() { // 正确清理计时器资源 timer?.cancel() timer = nil DispatchQueue.main.async { self.counterTime = 0 } isRunning = false isPaused = false } deinit { // 析构时确保计时器被销毁 timer?.cancel() timer = nil } }
关键修复说明
- 状态跟踪:添加
isRunning和isPaused变量,避免重复创建计时器、对无效计时器执行操作。 - 移除废弃标记:删除
.strict参数,使用系统默认的计时器创建方式。 - 循环引用处理:在事件处理器中使用
[weak self],打破计时器与类实例的循环持有关系。 - 资源清理:在重置和析构时主动取消并销毁计时器,确保资源正确释放。
内容的提问来源于stack exchange,提问作者chuanpham
相关产品推荐
相关产品推荐

