Combine中Timer.TimerPublisher无法启动,单例定时器不触发是什么原因?
问题根因
Timer.TimerPublisher 属于 Combine 框架中的冷发布者,创建后不会自动启动计时,必须主动调用connect()方法才会开始触发事件,这就是当前没有每秒打印日志的核心原因。
修复方案
给publisher加上.autoconnect()修饰符即可,这个修饰符会自动在订阅者绑定时调用connect()启动定时器,修改后代码如下:
import SwiftUI import Combine class TokenObserver: ObservableObject { // 此处添加.autoconnect() private let publisher = Timer.TimerPublisher(interval: 1.0, runLoop: .main, mode: .default).autoconnect() private let cancellable: AnyCancellable? static let instance = TokenObserver() let uuid = UUID() private init() { NSLog("TokenObserver.init()") self.cancellable = self.publisher.sink(receiveCompletion: { completion in NSLog("TokenObserver \(completion)") }, receiveValue: { date in NSLog("TokenObserver timestamp=" + ISO8601DateFormatter().string(from: date)) }) } deinit { NSLog("TokenObserver.deinit()") self.cancellable?.cancel() } } struct ContentView: View { var body: some View { Text("Hello, world! Instance = " + TokenObserver.instance.uuid.uuidString) .padding() } }
额外优化建议
- 如果后续要支持自定义计时间隔,可以把interval参数抽成init入参,或者提供对外的配置方法调整间隔,调整时记得销毁旧的publisher和cancellable重新创建即可
- 令牌校验属于轻量逻辑,放在主队列运行没有问题,如果后续逻辑变重可以改到后台队列执行,避免阻塞UI
内容的提问来源于stack exchange,提问作者BaronSharktooth
相关产品推荐
相关产品推荐

