1

我一直在观看 Apple 在 WWDC21 上的并发讨论,并阅读了大量有关 Apple 并发更新的文章;但是,我无法解决一件事:为什么人们会提供指导,告诉您应该使用 注释视图模型@MainActor?根据我的阅读,通过将视图模型属性设置为 a@StateObject@ObservedObject在视图中,它会自动变为@MainActor. 那么如果是这样的话,为什么人们仍然建议将视图模型注释为@MainActor

对于上下文,这里有一些我读过的文章参考了这个:

  1. https://www.hackingwithswift.com/quick-start/concurrency/understanding-how-global-actor-inference-works
  2. https://www.hackingwithswift.com/books/concurrency/how-to-use-mainactor-to-run-code-on-the-main-queue
  3. https://peterfriese.dev/swiftui-concurrency-essentials-part1/

摘自第一个链接:

[A] 任何使用带有 @MainActor 的属性包装器的结构或类作为其包装值将自动成为 @MainActor。这就是 @StateObject 和 @ObservedObject 在使用它们的 SwiftUI 视图上传达主要角色的原因——如果你在 SwiftUI 视图中使用这两个属性包装器中的任何一个,整个视图也会变成 @MainActor。

摘自第二个链接:

[W]无论何时你在视图中使用@StateObject 或@ObservedObject,Swift 都会确保整个视图在主要参与者上运行,这样你就不会意外地尝试以危险的方式发布 UI 更新。更好的是,无论您使用什么属性包装器,您的 SwiftUI 视图的 body 属性始终在主要参与者上运行。

这是否意味着您不需要将@MainActor 显式添加到可观察对象?好吧,不——将@MainActor 与这些类一起使用仍然有好处,尤其是如果它们使用 async/await 来完成自己的异步工作,例如从服务器下载数据。

总而言之,如果它会自动为我们处理,我对指导有点困惑。特别是因为我不知道在 SwiftUI 中有一个不是@ObservableObject.

我的最后一个问题,与第一个问题有关,是:如果@StateObject并且@ObservedObject自动生成视图@MainActor,那么是否@EnvironmentObject也生成视图@MainActor

为了在这之后添加一些代码,我打算使用以下类将以下类注入环境中.environmentObject(...)

@MainActor
class UserSettings: ObservableObject {
    @Published var flowUser: FlowUser?
    
    init(flowUser: FlowUser? = nil) {
        self.flowUser = flowUser
    }
}

以下是我的一个视图的视图模型:

@MainActor
class CatalogViewModel: ObservableObject {
    @Published var flowUser: FlowUser?
    
    init(flowUser: FlowUser?) {
        self.flowUser = flowUser
    }
}

如您所见,我已经创建了两个类@ObservableObjects,所以我觉得我应该能够删除@MainActor注释。

任何帮助将不胜感激!谢谢你的时间!

4

1 回答 1

1

@ObservedObject 或其他不会使其成为主要参与者。所以你的说法不正确

在第 22 分钟左右 见https://developer.apple.com/videos/play/wwdc2021/10019/在此处输入图像描述

根据我的阅读,通过在视图中将视图模型属性设为@StateObject 或@ObservedObject,它会自动变为@MainActor。

于 2022-01-28T09:40:49.310 回答