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

AsyncStream闭包未执行及Swift 6并发变量报错问题求助

问题分析与修复方案

问题1:AsyncStream闭包未执行(Timer回调未触发)

你的代码中Timer.scheduledTimer创建的定时器依赖RunLoop运行,若countdown(to:)函数在无活跃RunLoop的环境(如后台全局队列)中调用,定时器不会触发。同时原代码缺少停止定时器的逻辑,会导致定时器无限运行。

问题2:Swift 6并发安全警告

两个警告的核心是:在并发执行的Timer回调中访问、修改捕获的countdown变量存在数据竞争风险,Swift 6已将这类操作升级为错误。


完整修复代码

func countdown(to message: String) async throws {
    guard !message.isEmpty else { return }
    
    // 用Actor封装状态,保证并发安全
    actor Counter {
        var value = 3
        
        func next() -> String? {
            guard value > 0 else { return nil }
            let output = "\(value)..."
            value -= 1
            return output
        }
    }
    
    let counter = Counter()
    
    let stream = AsyncStream<String> { continuation in
        // 创建定时器,默认绑定主RunLoop
        let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak continuation] timer in
            Task {
                guard let countdownMessage = await counter.next() else {
                    // 倒计时结束,停止定时器并关闭流
                    timer.invalidate()
                    continuation?.finish()
                    return
                }
                continuation?.yield(countdownMessage)
            }
        }
        
        // 流终止时停止定时器,避免内存泄漏
        continuation.onTermination = { _ in
            timer.invalidate()
        }
    }
    
    for await countDownMessage in stream {
        try await say(countDownMessage)
    }
}

修复细节说明

  • 解决Timer触发问题:

    • 给AsyncStream的continuation添加onTermination回调,在流结束或取消时停止定时器,避免内存泄漏。
    • 依赖Timer.scheduledTimer默认绑定主RunLoop的特性,确保定时器能正常触发(非UI环境可手动将定时器添加到当前RunLoop并启动)。
  • 解决Swift 6并发安全问题:

    • 使用Actor封装countdown变量,Actor会自动保证对其属性的访问、修改操作线程安全,彻底消除数据竞争风险。
    • 在Timer回调中通过Task异步调用Actor的next()方法,安全获取倒计时消息。
  • 补充停止逻辑:

    • 当倒计时归0时,立即停止定时器并调用continuation.finish()结束AsyncStream,避免无限循环。

内容的提问来源于stack exchange,提问作者Fernando Ivan Perez Ruiz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:23:55