Grand Central Dispatch异步块内Timer未触发问题求助
为什么GCD异步块里的Timer在Playground中不工作?
核心原因有两个:
- Timer依赖RunLoop驱动:
Timer.scheduledTimer(withTimeInterval:repeats:block:)会把定时器自动加入当前线程的RunLoop,但GCD并发队列的异步任务执行完闭包后,对应的线程不会自动启动RunLoop,定时器根本没有机会被触发。 - Playground默认会提前终止:Playground在主线程代码执行完毕后就会停止运行,不会等待后台GCD队列里的任务或定时器继续执行,就算RunLoop能启动,Playground也早已经结束了。
修正后的代码示例:
import Foundation import PlaygroundSupport // 让Playground持续运行,不提前终止 PlaygroundPage.current.needsIndefiniteExecution = true let queue = DispatchQueue(label: "CustomQueue", attributes: .concurrent) queue.async { // 创建定时器并加入当前线程的RunLoop let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in print(3333) } // 手动启动当前线程的RunLoop,定时器才能被触发 RunLoop.current.run() }
补充说明:
- 引入
PlaygroundSupport并设置needsIndefiniteExecution = true,是为了阻止Playground在主线程代码跑完后直接结束,让它能持续监听定时器事件。 - 在GCD异步块里调用
RunLoop.current.run(),会让线程停在RunLoop循环中,定时器才有机会被调度执行。 - 如果是重复定时器,记得在不需要的时候调用
timer.invalidate()销毁它,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Kim Mỹ
相关产品推荐
相关产品推荐

