好的,那么SwiftUI
和ObservableObject
,在iOS 13上,我有实现ObservableObject
的Model
class Model: ObservableObject {
@Published public var toggle: Bool = false
init() {
NSLog("Model init")
objectWillChange.sink { void in
NSLog("1 toggle \(self.toggle)")
}
$toggle.sink { v in
NSLog("2 toggle \(self.toggle) -> \(v)")
}
}
}
还有一个按钮,可以切换toggle
struct ContentView: View {
@ObservedObject var model: Model
var body: some View {
Button(action: {
self.model.toggle.toggle()
}, label: {Text(model.toggle ? "on" : "off")})
}
}
现在,这是可行的。你按下按钮,它会在“打开”和“关闭”之间切换。(在制作toggle
@Published
之前,它没有这么做。)但是,日志记录不像预期的那样工作。我在启动时立即获得两个日志:"Model“和"2切换假-> false”。点击按钮,虽然显然改变了toggle
的值,但并不会导致任何一个闭包的执行。
当视图改变您的模型时,我希望有一种方法来了解更改的情况,以防您需要更新计算值或同步到磁盘或其他东西。也许sink
是错误的方法?
在更新字段时,如何通知具有ObservableObject
字段的@Published
字段?
发布于 2020-01-21 22:33:35
sink
函数返回值的最新文档:
/// - Returns: A cancellable instance; used when you end assignment of the received value. Deallocation of the result will tear down the subscription stream.
从本质上说,这意味着接收器可以生成Subscriber
,但不会保留它。一旦您的init完成,订阅服务器就会被删除并从内存中删除。您需要通过创建这样一个强大的引用来保持它们:
class Model: ObservableObject {
@Published public var toggle: Bool = false
var changeSink: AnyCancellable?
var toggleSink: AnyCancellable?
init() {
NSLog("Model init")
changeSink = objectWillChange.sink { void in
NSLog("1 toggle \(self.toggle)")
}
toggleSink = $toggle.sink { v in
NSLog("2 toggle \(self.toggle) -> \(v)")
}
}
}
我使用的Combine
不多,但您可能经常考虑的另一种方法是向属性添加一个didSet
,如下所示:
public var toggle: Bool = false {
didSet {
print("1 toggle \(self.toggle)")
}
}
发布于 2020-01-21 22:59:44
您的ObservableObject类Model是正确的,但是:
1. ObjectWillChange应该是ObservableObjectPublisher()类型。
,它将objectWillChange属性创建为ObservableObjetPublisher的实例。这来自组合框架,这就是为什么您需要添加导入组合以使代码编译。一个可观察的对象发布者的工作很简单:每当我们想告诉世界我们的对象已经改变了,我们就要求发行者为我们做这件事。
2.您需要观察的属性(Toggle)应该以如下方式实现:
var toggle = "" {
willSet {
objectWillChange.send()
}
}
第二,我们在模型的Toggle属性上附加了一个willSet属性观察者,这样我们就可以在值发生变化时运行代码。在我们的示例代码中,每当切换更改时,我们都调用objectWillChange.send(),这就是告诉objectWillChange发布者发布我们的数据已经更改的消息,以便任何订阅的视图都可以刷新。
确保类模型符合@ObservedObject,并且它的实例被标记为 ObservableObject
,因为您的模型类符合ObservableObject,所以您可以像使用任何其他@ObservedObject属性一样使用它。所以,我们可以用它来观看切换,就像这样:
struct ContentView: View {
@ObservedObject var model: Model
var body: some View {
Button(action: {
self.model.toggle.toggle()
}, label: {Text($model.toggle ? "on" : "off")})
}
}
https://stackoverflow.com/questions/59852106
复制相似问题