主要观点:
- SwiftUI 的公共 API 只是冰山一角,私有的 AttributeGraph 框架幕后跟踪应用的各个方面以决定更新时机,它是 SwiftUI 运行的基础。
- 掌握 AttributeGraph 中依赖关系的工作原理对编写高级 SwiftUI 代码至关重要,但因其是闭源框架的私有实现细节,难以获取相关信息。
- 通过创建
Setting
示例来探索 SwiftUI 如何传播变化,实现一个简单的UserDefaults
包装器,解决了 SwiftUI 中视图更新与存储值的问题。 - 理解 SwiftUI 中
State
的生命周期和依赖关系,包括如何处理外部更新、使用反射 introspection 来窥探State
的内部结构等。
关键信息:
- AttributeGraph 是 SwiftUI 运行的基础,提供了声明式 UI 框架所需的属性图和数据依赖跟踪。
Setting
是一个简单的UserDefaults
包装器,通过Binding
与 SwiftUI 控件配合使用。- 在实现
Setting
时遇到了编译器错误,通过使用nonmutating
修饰符解决了问题。 - 为了让 SwiftUI 更新视图,需要使用
DynamicProperty
协议,将Setting
conform 到该协议。 State
的 getter 和 setter 有特殊的行为,getter 会通知 SwiftUI 值已被读取,setter 会触发视图更新。- 处理外部更新时,需要使用 KVO 来响应
UserDefaults
的变化,并在Setting
中添加观察者来通知 SwiftUI。 - 使用反射 introspection 可以窥探
State
的内部结构,发现_location
属性在不同情况下的变化,以及 SwiftUI 如何设置_location
以进行依赖跟踪。
重要细节:
- 在实现
Setting
的wrappedValue
时,最初使用普通的 setter 会导致编译器错误,因为self
是不可变的,通过使用nonmutating
修饰符解决了问题。 - 在使用
Setting
时,需要将Setting
conform 到DynamicProperty
协议,以便 SwiftUI 能够识别和处理依赖关系。 - 在处理外部更新时,需要在
Setting
中添加观察者,通过 KVO 来响应UserDefaults
的变化,并在观察者的回调函数中更新_update
属性,以通知 SwiftUI 进行视图更新。 - 在使用反射 introspection 时,通过打印
__update
可以窥探State
的内部结构,发现_location
属性在不同情况下的变化,以及 SwiftUI 如何设置_location
以进行依赖跟踪。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。