我一直在观看WWDC 21的Apple并发会谈,以及阅读大量关于Apple并发更新的文章;然而,我无法理解一件事:为什么人们提供指导,您应该使用@MainActor
注解视图模型?根据我所读到的,通过在视图中将视图模型属性设置为@StateObject
或@ObservedObject
,它会自动变为@MainActor
。因此,如果是这种情况,为什么人们仍然推荐将视图模型标注为@MainActor
?
作为上下文,这里有一些我读过的文章提到了这一点:
- https://www.hackingwithswift.com/quick-start/concurrency/understanding-how-global-actor-inference-works
- https://www.hackingwithswift.com/books/concurrency/how-to-use-mainactor-to-run-code-on-the-main-queue的
- https://peterfriese.dev/swiftui-concurrency-essentials-part1/的
摘自第一个链接:
[A]ny使用属性 Package 器并将@MainActor作为其 Package 值的struct或class将自动为@MainActor。这就是为什么@StateObject和@ObservedObject在使用它们的SwiftUI视图上传达了main-actor-ness-如果您在SwiftUI视图中使用这两个属性 Package 器中的任何一个,则整个视图也将成为@MainActor。
摘自第二个链接:
当你在视图中使用@StateObject或@ObservedObject时,Swift会确保整个视图都在main actor上运行,这样你就不会意外地尝试以危险的方式发布UI更新。更棒的是,无论你使用什么属性 Package 器,SwiftUI视图的body属性总是在main actor上运行。
这是否意味着你不需要显式地将@MainActor添加到可观察对象中?嗯,不--在这些类中使用@MainActor仍然有好处,尤其是当它们使用Abldc/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
注解。
任何帮助将不胜感激!感谢您的时间!
2条答案
按热度按时间nzrxty8p1#
一个@ObservedObject或其他对象并不能使它成为一个主参与者。
在第22分钟左右见https://developer.apple.com/videos/play/wwdc2021/10019/ x1c 0d1x
根据我所读到的,通过在视图中将视图模型属性设置为@StateObject或@ObservedObject,它会自动变为@MainActor。
unftdfkk2#
我的理解是
1.如果ViewModel可能用于SwiftUI以外的上下文,(例如,在应用程序中基于UIKit的部分或更一般的Swift上下文中),显式地用@MainActor标记它可以确保它的行为正确。我们都知道SwiftUI视图本质上是主线程绑定的,它们的生命周期和状态更改都在主线程上管理,但如果你的viewModel被用在其他地方,情况可能就不是这样了。
1.使用@MainActor显式注解ViewModel可以向任何阅读代码的人指示这是要在主线程上使用的。它可以在较大的团队中帮助提高可读性。