@EnvironmentObject 用于在多个视图之间共享状态,当前视图中与上层视图经环境传递的 ObservableObject 实例之间创建关联的属性包装器。 允许某个视图树中的所有子视图访问相同的对象,而无需显式传递。
作用:@EnvironmentObject用于在整个应用程序中共享全局环境对象。它允许在应用程序中的任何地方访问和使用该对象,而无需手动传递数据。在 SwiftUI 中,View 提供了 environmentObject(自定义的Object) 方法,来把某个 ObservableObject 的值注入到当前 View 层级及其子层级中去。在这个 View 的子层级中,可以使用 @EnvironmentObject 来直接获取这个绑定的环境值。@EnvironmentObject 修饰器是针对全局环境的。通过它,我们可以避免在初始 View 时创建 ObservableObject, 而是从环境中获取 ObservableObject。
应用场景
- 当需要在多个视图间共享同一个数据模型时,如用户设置、主题或应用状态。
- 适用于构建复杂的视图层级,其中多个视图需要访问同一个
ObservableObject
实例。
注意事项
- 使用 @EnvironmentObject 前,必须确保已在视图层级的上游提供了相应的实例( 通过 .environmentObject 修饰器 ),否则将导致运行时错误。
- 它对视图的更新触发条件与 @StateObject 和 @ObservedObject 一样。
- 与 @ObservedObject 一样, @EnvriomentObject 支持动态切换关联的实例。
- 只在必要时引入 @EnvironmentObject,否则会引发视图不必要的视图更新。通常情况下,会有多个视图从不同层级观察并响应同一个实例,必须合理优化才能避免应用性能劣化。这也是很多开发者不喜欢 @EnviromentObject 的原因。
- 在一个视图层次中,同一个类型的环境对象只有一个实例有效。
使用示例
class UserSettings: ObservableObject {
@Published var username = "Guest"
}
struct ParentView: View {
@StateObject var settings = UserSettings()
var body: some View {
ChildView().environmentObject(settings)
}
}
struct ChildView: View {
@EnvironmentObject var settings: UserSettings
var body: some View {
Text("Username: \(settings.username)")
}
}
@Environment与@EnvironmentObject区别
- @Environment 属性包装器只能获取已经存在于环境中的环境变量的值
- @EnvironmentObject 属性包装器结合 ObservableObject 协议来创建和传递自定义的环境对象