SwiftUI中每40秒调用API异常:触发时间随机问题咨询
问题原因
你使用的Timer.publish指定了in: .common运行循环模式,该模式下定时器事件优先级较低。当主线程被UI渲染、用户交互等高优先级任务占用时,定时器触发会被推迟,导致看起来触发时间随机。
解决方案
方案一:调整运行循环模式
将运行循环模式改为.default,提升定时器事件优先级,减少被延迟的概率:
func startTimer() { timer = Timer.publish(every: 40.0, on: .main, in: .default) .autoconnect() .sink { _ in // API call } }
方案二:使用GCD定时器实现精准定时
如果需要更高精度的定时,推荐用DispatchSourceTimer,它基于GCD实现,不依赖RunLoop,受主线程阻塞的影响更小:
var timer: DispatchSourceTimer? func startTimer() { timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global()) // 首次立即触发,之后每40秒触发一次,允许100毫秒误差 timer?.schedule(deadline: .now(), repeating: 40.0, leeway: .milliseconds(100)) timer?.setEventHandler { [weak self] in // 执行API调用 // 若需更新UI,切换回主线程 DispatchQueue.main.async { // 处理UI相关逻辑 } } timer?.resume() } // 记得在合适时机(如页面销毁、APP退后台)取消定时器 func stopTimer() { timer?.cancel() timer = nil }
注意:无论哪种方案,APP进入后台后系统会限制后台任务运行时间,定时器可能无法持续精准触发,若需后台持续执行需申请对应权限。
内容的提问来源于stack exchange,提问作者Vinay Bhardwaj
相关产品推荐
相关产品推荐

