并发 MainActor 崩溃:root.user-initied-qos.cooperative

问题描述 投票:0回答:1

以下代码(为简洁起见进行了简化)会导致崩溃:

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()
}

根据我的理解,分配

self.thing
是安全完成的,因为它的调用者被分配给主要参与者(从而继承)。这里出了什么问题?

swift concurrency actor
1个回答
0
投票

与 GCD 不同,在 Swift 并发中,

getThing
的 actor 隔离取决于
getThing
的声明方式,而不是由 actor 与其调用位置的隔离决定。事实上,您从与主要参与者隔离的任务中调用它这一事实并不重要。如果你想让
getThing
跑男主角,你有两个选择:

  1. getThing
    与主角隔离:

    class Foo: ObservableObject
        @Published var thing: Thing?
    
        func start() {
            Task { await getThing() }
        }
    
        @MainActor
        func getThing() async {
            self.thing = await foo.fetchThing()
        }
    }
    
  2. 或者,您可以将整个班级与主要演员隔离,这将有效地将

    getThing
    与主要演员隔离:

    @MainActor
    class Foo: ObservableObject
        @Published var thing: Thing?
    
        func start() {
            Task { await getThing() }
        }
    
        func getThing() async {
            self.thing = await foo.fetchThing()
        }
    }
    
© www.soinside.com 2019 - 2024. All rights reserved.