swift 将@MainActor添加到@Published var是否会更改其父类的actor?

oknwwptz  于 2023-05-05  发布在  Swift
关注(0)|答案(1)|浏览(93)

下面是一个例子:

import SwiftUI

class VM:ObservableObject{
    @Published var keepStuff = 0
    
    init(){
        keepStuff = 1
    }
}

struct MyView:View{
    
    @ObservedObject var vm = VM()
    
    var body: some View{
        Text("Hello World")
        Text(String(vm.keepStuff))
    }
}

这不会产生错误消息,并且按预期工作。现在,如果我把@MainActor加到keepStuff上,我会得到一个
注意:这个属性的变化只允许在参与者内部
例如,

@MainActor @Published var keepStuff = 0

class VM:ObservableObject{
    @MainActor @Published var keepStuff = 0
    
    init(){
        keepStuff = 1
    }
}

如果我@MainActor整个类或init,错误显然会消失。
我的理解是,@Published var总是自动成为主actor的一部分,因此,当从任何非主actor更新@Published var时,您会遇到错误。这里看起来几乎像是将@MainActor添加到@Published var,使得类的其余部分不再是MainActor的一部分。
有人能解释一下这种行为吗?

wwwo4jvm

wwwo4jvm1#

我刚刚做了一个快速测试,发现使用@MainActor @Published并不能使类@MainActor也一样。也就是说,类中声明的任何async func都运行在后台线程上,而不是主线程上,就像如果类是@MainActor一样。

//@MainActor
class TestObject: ObservableObject {
    @MainActor @Published var count = 0
     
    func test() async {
       // here it is on main thread if class is @MainActor and background thread if isn't (even with @MainActor @Published above)
        do {
            try await Task.sleep(for: .seconds(2)) // put break point here to check the thread
        }
        catch {
            return // cancelled
        }

        await MainActor.run { // or Task { @MainActor in seen in Apple's FoodTruck sample
            count+=1
        }
    }
}

struct MyView: View {
   @StateObject var object = TestObject()

   var body: some View {
        Text("Test)
        .task {
             await object.test()
        }
    }
}

相关问题