由Combine框架定义的ObservableObject
协议具有一个objectWillChange
发布者属性,该属性可让您知道此对象的属性何时会更改,这意味着,如果该发布者将在获取此将要更改的事件时读取其值,但仍会在更改前 读取其值,我想了解的是:
ObservableObject
的实际新值?谢谢
答案 0 :(得分:6)
SwiftUI不知道ObservableObject
实际上 是否已更改。 SwiftUI信任您。如果您告诉它对象将更改(通过使objectWillChange
发出输出),则SwiftUI将假定对象已更改,并计划显示更新。
我不确定100%为什么苹果选择objectWillChange
作为信号。在WWDC 2019上,该属性实际上是didChange
,而不是objectWillChange
。他们在Xcode 11仍处于测试版时对其进行了更改。也许他们所做的是在objectWillChange
发出时获取对象的状态,然后稍后在更新屏幕时再次获取对象,然后以某种方式比较这些值。
关于objectWillChange
发出后如何获取对象的值,这取决于您。 SwiftUI通过注册CFRunLoopObserver
活动的.beforeWaiting
来实现这一目的。观察者运行时,它将重新呈现ObservableObject
发出信号的所有视图。
请注意,如果您使用@Published
属性将值存储在ObservableObject
中,则可以使用$
前缀来订阅属性的发布者。例如:
class MyObject: ObservableObject {
@Published var value: Int = 0
}
let object = MyObject()
let ticket = object.$value
.sink { print("new value: \($0); old value: \(object.value)") }
object.value = 1
Published
包装器在您订阅时发布当前值,然后在每次更改时发布新值。但是请注意,它会在存储新值之前 进行发布,如上面的示例代码所示,输出如下:
new value: 0; old value: 0
new value: 1; old value: 0
答案 1 :(得分:1)
我所做的是添加到我需要更改
之后知道的每个ObservableObjectpublic var objectDidChange = ObservableObjectPublisher()
您可以订阅并在一切更改后手动调用 .send()
。
答案 2 :(得分:0)
SwiftUI通过ObservableObject
包装器监听@ObservedObject
事件
/// A dynamic view property that subscribes to a `ObservableObject` automatically invalidating the view /// when it changes. @available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *) @propertyWrapper public struct ObservedObject<ObjectType> : DynamicProperty where ObjectType : ObservableObject {
看起来像DynamicProperty
,这就是他们所说的
/// Represents a stored variable in a `View` type that is dynamically /// updated from some external property of the view. These variables /// will be given valid values immediately before `body()` is called. @available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *) public protocol DynamicProperty { /// Called immediately before the view's body() function is /// executed, after updating the values of any dynamic properties /// stored in `self`. mutating func update() }
因此,ObservedObject
包装器会监听来自ObservableObject
的已发布事件,并且一旦调用update()
就会提供最新值(如果需要,很可能直接为其重新缓存以代替更新)致电)。