SwiftUI:@State,@Binding,@ObservedObject和@EnvironmentObject的使用场景

在使用UIKit开发时,我们通常会拿到一个view的引用,然后通过这个引用去修改view的外观。

但在SwiftUI中,所有view的外观都是对“状态”的响应,因此我们不会直接去修改view,而是修改“状态”。

也就是说,我们只需要改变“状态”,view检测到变化并自动的刷新。

SwiftUI提供了几种保存状态的方式,来保证数据的“真实来源”(source of truth)。本文就来介绍它们各自的区别。

@State

@State修饰的数据只用于当前view内部使用,所以@State常与Private搭配使用。

而且通常用于修饰简单的数据类型,如(Int, Double, String, Bool) 。

private @State var name: String = ""

@Binding

@Binding和@State搭配使用的,父view用@State,子view用@Binding,以实现父view和子view的数据绑定。

当数据是从外部传递的,并且需要和外部保持绑定时,就用@Binding修饰该变量。

@ObservedObject

和@State类似,但@ObservedObject用于修饰复杂的数据类型,而且只能修饰引用类型的数据。

所以,如果你想要修饰一个复杂的struct数据,首先需要用class来包裹这个struct。

final class MyClass: ObservableObject {
	@Published var myStruct = MyComplexStruct()
}

//在view里可以这样定义
@ObservedObject var myClass = MyClass()
// myClass就像是被@State修饰的简单数据。

可以用于组件之间的 数据传递。

@EnvironmentObject

如果对象存活于整个app生命周期,并且大量view需要共享此对象,那么用@EnvironmentObject修饰就再好不过了(比如用户信息对象)。

当然,你可以用@ObservedObject来达到同样的目的,但你需要通过view1传给view2,传给view3...传递链条太长了。此时,用@EnvironmentObject就显得方便许多了。

参考资料:

https://www.hackingwithswift.com/quick-start/swiftui/whats-the-difference-between-observedobject-state-and-environmentobject

原文地址:https://www.cnblogs.com/ZJT7098/p/13984422.html