我一直在观看 Apple 在 WWDC21 上的并发演讲,并阅读了大量有关 Apple 并发更新的文章;但是,我无法理解一件事:为什么人们会提供应该使用
@MainActor
注释视图模型的指导?根据我的阅读,通过将视图模型属性设置为视图中的 @StateObject
或 @ObservedObject
,它会自动变为 @MainActor
。那么如果是这样的话,为什么人们仍然建议将视图模型注释为@MainActor
?
对于上下文,以下是我读过的一些引用此内容的文章:
摘自第一个链接:
[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
注释。
任何帮助将不胜感激!感谢您的宝贵时间!
@ObservedObject 或其他对象并不使其成为主要参与者。所以你的说法不正确
参见 https://developer.apple.com/videos/play/wwdc2021/10019/ 大约第 22 分钟
根据我所读到的内容,通过将视图模型属性设置为视图中的 @StateObject 或 @ObservedObject,它会自动变为 @MainActor。
我的理解是这样的