Data Flow
State
Property wrapper State只是一个映射, 并不真正开放空间存储变量, 真正的空间开辟是这样的过程:
State必须定义在某个ViewA: View中作为成员属性, 不能定义在别的地方, 也不能定义成optional, 也不能定义成static变量.- SwiftUI 在
ViewA对象生成时, 通过某种和DynamicProperty相关的机制(可能是某种 reflection 机制, 也可能是 compiler synthesize), 根据State中指示的 initial value, 在真正的 view[1] 对象中建立了一份数据, 并把ViewA和其所有State的成员变量作出了 Model -> View 的关联. - 之后
ViewA.body每次被重新调用 (例如 data change 导致的 update 或者 view 重新出现在屏幕上等) 前, 都会保证ViewA中可以访问到的值被更新到与内存中的运行时状态一致, 这样之后访问/操纵该值时, 本质上都是访问了对应的真正的与 view 关联的数据对象. - 在 SwiftUI 可以监控到的环境下调用到某个
State的 getter 的前提下, 我们只要在任何地方触发这个State的 setter, 就有可能触发获取了 getter 的body的重新调用.- 当
Statewrap 的类型是非Equatable时, 只要触发 setter, 即触发body被调用. - 当
Statewrap 的类型遵循Equatable时, 只有触发 setter 时的newValue和旧值不同时, 才会触发body.
- 当
注意在非 SwiftUI 体系下, State毫无作用, 甚至基本的 get/set 逻辑都不满足.
State所指示对象的生命期
无论是State, 还是我们自定义的struct ViewA, 本质上都只是 recipe, 不是真正的运行时对象. 真正的运行时对象, 要么被 SwiftUI 很好地隐藏在真正的 runtime view 对象中, 要么在我们自定义的别的 reference type 中(类似下文的ObservableObject).