You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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ỹ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 13:17:36