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
的重新调用.- 当
State
wrap 的类型是非Equatable
时, 只要触发 setter, 即触发body
被调用. - 当
State
wrap 的类型遵循Equatable
时, 只有触发 setter 时的newValue
和旧值不同时, 才会触发body
.
- 当
注意在非 SwiftUI 体系下, State
毫无作用, 甚至基本的 get/set 逻辑都不满足.
State
所指示对象的生命期
无论是State
, 还是我们自定义的struct ViewA
, 本质上都只是 recipe, 不是真正的运行时对象. 真正的运行时对象, 要么被 SwiftUI 很好地隐藏在真正的 runtime view 对象中, 要么在我们自定义的别的 reference type 中(类似下文的ObservableObject).