SwiftUI中的objectWillChangeSequence与onChange修饰符相比有什么作用?

4

这个示例来自于 WWDC22 的视频 The SwiftUI cookbook for navigation

创建一个 NavigationModel 以存储导航路径。

  • 当视图出现时,如果存在,则使用 SceneStorage 的数据加载 NavigationModel
  • 每当 NavigationModel 发生更改时,通过观察自定义的 objectWillChangeSequence 计算属性将其数据表示保存在 SceneStorage 中。

最后一点让我感到好奇:为什么不使用 .onChange 修饰符呢?像这样:

.onChange(of: navModel.path) { _ in
    data = navModel.jsonData
}

注意:`objectWillChangeSequence`属性的定义如下:
var objectWillChangeSequence: AsyncPublisher<Publishers.Buffer<ObservableObjectPublisher>> {
    objectWillChange.buffer(size: 1, prefetch: .byRequest, whenFull: .dropOldest).values
}

enter image description here


有很多方法可以完成同样的事情,您能指定出问题出在哪里吗? - Asperi
1
为什么苹果会用一个对于初学者来说很难理解的属性来举例,尤其是已经有了一个广泛使用的.onChange修饰符来解决这个问题? - parapote
1个回答

2
视频中展示的示例中有许多错误。
其中一个错误是Recipe结构体具有let id = UUID(),这意味着即使恢复了导航路径,之前查看过的食谱也永远无法找到,因为它与持久化时的id不同。
我们可以快速修复它:
struct Recipe: Hashable, Identifiable {
    var id: String {
        return name
    }

现在,@SceneStorage 将开始工作,我们可以测试将其替换为 .onChange
我们很快发现,NavigationModel 不仅包括 recipePath,还有 selectedCategorycolumnVisibility。如果我们使用 onChangejsonData,那么我们会不必要地进行编码以检查是否有变化。

我可以问一下,为什么需要在应用程序启动时存储导航数据/路径,而不是在启动时创建它?这真的有意义吗? - Giuseppe Mazzilli
@GiuseppeMazzilli 它给人一种错觉,即使一个应用程序被关闭,它仍然在运行。但更重要的是,如果你想支持多窗口的iPad应用程序,你需要状态恢复,否则用户将不断打开标签,当它们被关闭时,它们将回到原始状态,就好像它们从未有过任何内容一样。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接