组合:初始化突变'self'参数



我弄乱了组合代码和 Swift UI,遇到了这个问题。实际上,我想将Publisher传递到View中,并在每次发布者发布更新时View更新该更新。

下面是一个无法编译的示例游乐场。相反,它会提出一个错误 -Escaping closure captures mutating 'self' parameter.sink(...行上。

import Combine
import SwiftUI
struct MyView: View {
let cancellable: AnyCancellable
@State var current: Int = 0
init<P>(publisher: P) where P: Publisher, P.Output == Int, P.Failure == Never {
cancellable = publisher.sink { value in
self.current = value
}
}
var body: some View {
Text("(current)")
}
}
let subject = PassthroughSubject<Int, Never>()
let x = MyView(publisher: subject)
subject.send(5)

目前,我已经更改了代码以使用包含值的ObservableObject视图模型,并告诉该对象发送更新。但是我很感兴趣其他人如何解决这个问题,因为我也想要一个无视图模型选项。

你们做了什么?

您可以使用onReceive在 SwiftUIViews 中订阅 CombinedPublishers。这样,SwiftUI 运行时将为您管理订阅,即使您的视图可能会多次重新创建。

struct MyView: View {
@State var current: Int = 0
var body: some View {
Text("(current)")
.onReceive(somePublisher) { self.current = $0 }
}
}

但是,直接使用ObservableObject通常是一个更好的主意,因为它们直接集成到 SwiftUI 中。

目前我正在做这样的事情:

import Combine
import SwiftUI
import PlaygroundSupport
class Model: ObservableObject {
var current: Int = 0 {
willSet {
self.objectWillChange.send()
}
}
}
struct MyView: View {
@EnvironmentObject var model: Model
var body: some View {
Text("(model.current)")
}
}
let model = Model()
let myView = MyView().environmentObject(model)
PlaygroundPage.current.liveView = UIHostingController(rootView: myView)
model.current = 5

最新更新