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

Concurrency MainActor崩溃排查:root.user-initiated-qos.cooperative

崩溃原因分析与修复方案

崩溃信息

Crashed: com.apple.root.user-initiated-qos.cooperative

触发代码

@Published var thing: Thing?

func start() {
    Task { @MainActor in await getThing() }
}

func getThing() async {
    self.thing = await foo.fetchThing()
}

问题根源

你误以为start()里的@MainActor会让getThing()全程保持MainActor上下文,但实际并非如此:

  • 虽然getThing()是在MainActor的上下文中被调用,但执行到await foo.fetchThing()时,当前任务会被挂起;
  • 异步操作完成后,系统会从全局线程池中选取一个可用线程恢复任务执行,此时不再处于MainActor线程;
  • 而@Published属性的赋值必须在MainActor(主线程)上执行,非主线程赋值就会触发崩溃。

修复方案

有两种可靠的修复方式:

方式一:给getThing()标注@MainActor

强制整个方法的执行上下文绑定MainActor,确保赋值操作在主线程完成:

@Published var thing: Thing?

func start() {
    Task { @MainActor in await getThing() }
}

@MainActor
func getThing() async {
    self.thing = await foo.fetchThing()
}

方式二:显式切换到MainActor执行赋值

在获取到数据后,通过MainActor.run将赋值操作切回主线程:

@Published var thing: Thing?

func start() {
    Task { @MainActor in await getThing() }
}

func getThing() async {
    let fetchedThing = await foo.fetchThing()
    await MainActor.run {
        self.thing = fetchedThing
    }
}

内容的提问来源于stack exchange,提问作者Aaron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:12:05