如果willSet属性在ObservableObject更改之前立即发出更改通知,则@ObservedObject如何刷新UI?

时间:2020-08-19 09:39:08

标签: swiftui

swiftUI的新手,只是试图了解hackingwithswift的本部分教程,并试图在swift.org中查找willSet的文档,但我觉得我可能误会了它的实际工作原理。

这是代码(评论是我的):

class DelayedUpdater: ObservableObject {
    var value = 0 {
        // call this code right before the object changes, which is what willSet does.
        willSet {
            // this sends the change notification manually so that any views using this value will refresh.
            objectWillChange.send()
        }
    }

    init() {
        for i in 1...10 {
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(i)) {
                self.value += 1
            }
        }
    }
}

struct ContentView: View {
    @ObservedObject var updater = DelayedUpdater()

    var body: some View {
        Text("Value is: \(updater.value)")
    }
}

我不了解的是,如果willSetobjectWillChange.send()在值更改之前立即发送了更改通知。我假设此通知首先到达@ObservedObject,然后刷新UI。但是我的问题是,刷新UI的时间是在值更改之前还是之后?我知道它看起来好像是在更改之后,但是willSetobjectWillChange.send()文档建议它在更改之前立即发送更改通知。

如果是这种情况,并且刷新发生在实际更改之前,UI如何用newValue刷新?

1 个答案:

答案 0 :(得分:1)

值更改和UI更新都在主队列上运行,并且只有一个队列。在SwiftUI的主队列中的值更新任务可以运行之前,该值已经更新。

那么为什么在值更新之前发送消息?因为那样,SwiftUI就有机会观察先前的值来为任何动画做准备。这意味着SwiftUI的一部分正在另一个队列上运行,但是当需要实际更新值时,SwiftUI将安排一个任务在主队列上运行,并且该值将在那时更新。