属性包装器: - 属性(简单值或者对象)更改后,按照规则,跟属性绑定的UI都会重新渲染,
@State 修饰简单的值,只适合于struct,当然这个struct可以是常用的Double, Int, String等类型,单个视图的局部更新。
@Binding 双向传值,当前视图和所有子视图共享数据,
当前视图修改值,会通过Binding通知所有子视图进行局部刷新。
任何一个子视图修改值,也会通过Binding传递到父视图进行局部刷新。
***@StateObject和@ObservedObject都是用来包装实现了ObservableObject协议的属性,唯一的区别就是该属性的生命周期的管理问题。***
@StateObject 修饰对象,当前视图和所有子视图共享数据,监听数据的所有视图局部刷新,生命周期由View管理,只初始化一次,View销毁它就销毁
@ObservedObject 修饰对象,当前视图和所有子视图共享数据,监听数据的所有视图局部刷新,生命周期由我们手动管理,通常由父传给子,可能会随时释放。并且需要遵循 ObservableObject协议,因为ObservableObject继承与AnyObject,所以只有class才有资格遵守该协议,比如 class User: ObservableObject { }//协议是空协议,没有任何必须实现
************ 上面2种修饰 比如 A显示B,B显示C,C显示D,
那么A修饰了属性property,如果D想使用此属性,那么需要A传递B,B传递C,C传递D,可以共享********
@EnvironmentObject 修饰对象,将对象放在环境中,当前视图和所有子视图共享数据,监听数据的所有视图局部刷新。
************ 上面1种修饰 比如 A显示B,B显示C,C显示D,
那么A修饰了属性property,B和C不关心属性,只有D需要该属性,那么就用此修饰,可以直接在D取该属性********
@Environment 修饰对象,全局属性,系统属性,可以随时取,可以通过扩展自定义整个工程的全局字典属性。
简单举例,取日历:@Environment(\.calendar) var calendar: Calendar
exp.