Erh*_*nis 10 observable ios swift swiftui
好的,所以 SwiftUI 和 ObservableObject,在 iOS 13 上。我有实现 ObservableObject 的模型:
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)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
和一个可以切换的按钮toggle
:
struct ContentView: View {
@ObservedObject var model: Model
var body: some View {
Button(action: {
self.model.toggle.toggle()
}, label: {Text(model.toggle ? "on" : "off")})
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这有效。你按下按钮,它会在“开”和“关”之间切换。(在 make 之前toggle
@Published
,它没有。)但是,日志记录没有按预期工作。我在启动时立即得到两个日志:“Model init”和“2 toggle false -> false”。点击按钮,虽然显然改变了 的值toggle
,但不会导致执行任何一个闭包。
当视图改变您的模型时,我希望有一种方法可以通知更改,以防您需要更新计算值或同步到磁盘或其他内容。也许sink
是错误的方法?
当字段更新时如何通知ObservableObject
with@Published
字段?
Joe*_*Joe 12
sink
函数返回值的最新文档:
/// - Returns: A cancellable instance; used when you end assignment of the received value. Deallocation of the result will tear down the subscription stream.
本质上,这意味着 sink 生成 aSubscriber
但不保留它。一旦您的初始化完成,订阅者就会被拆除并从内存中删除。您需要通过创建这样的强引用来保留它们:
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)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
我用的不多,Combine
但我经常看到的另一种方法是,您可能会考虑将 a 添加didSet
到您的属性中,如下所示:
@Published public var toggle: Bool = false {
didSet {
print("1 toggle \(self.toggle)")
}
}
Run Code Online (Sandbox Code Playgroud)
您的 ObservableObject 类模型已正确完成,但是:
1. ObjectWillChange 应该是 ObservableObjectPublisher() 类型。
这会创建一个 objectWillChange 属性作为 ObservableObjetPublisher 的实例。这来自于Combine 框架,这就是为什么你需要添加import Combine 来编译你的代码。可观察对象发布者的工作很简单:每当我们想告诉全世界我们的对象发生了变化时,我们都会要求发布者为我们做这件事。
2.你需要观察的属性(Toggle)应该这样实现:
var toggle = "" {
willSet {
objectWillChange.send()
}
}
Run Code Online (Sandbox Code Playgroud)
其次,我们有一个 willSet 属性观察器附加到 Model 的 Toggle 属性,以便我们可以在该值更改时运行代码。在我们的示例代码中,每当切换更改时,我们都会调用 objectWillChange.send(),这会告诉 objectWillChange 发布者发布我们的数据已更改的消息,以便任何订阅的视图都可以刷新。
3.确保你的类Model符合ObservableObject,并且它的实例用@ObservedObject标记
由于您的模型类符合 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")})
}
}
Run Code Online (Sandbox Code Playgroud)
希望这有帮助,参考:https : //www.hackingwithswift.com/quick-start/swiftui/how-to-send-state-updates-manually-using-objectwillchange
归档时间: |
|
查看次数: |
7420 次 |
最近记录: |