我有一个
Updater
类,它使用 Combine
检查一个状态然后更新另一个状态。如果我在视图中初始化 Updater
,它工作正常,但每次重绘视图时它都会再次初始化。如果我在视图之外初始化 Updater
,则状态更新时不会调用组合过程,即 sink
仅被调用,而不是在更新 firstCount
时被调用。
使用
Combine
的Updater类:
class Updater {
private var cancellables = Set<AnyCancellable>()
func setup(appState: AppState) {
CurrentValueSubject<Int, Never>(appState.firstCount)
.map {
$0 * 10
}
.sink { value in
print("Sink \(value)")
DispatchQueue.main.async {
appState.resultCount = value
}
}
.store(in: &cancellables)
}
}
国家:
@Observable class AppState {
var firstCount: Int = 0
var resultCount: Int = 0
}
初始化
BackgroundTask
的 App 结构体:
@main
struct TestCombineInViewApp: App {
var appState: AppState = AppState()
private let updater: Updater
init() {
let appState = AppState()
self.appState = appState
updater = Updater()
updater.setup(appState: appState)
}
var body: some Scene {
WindowGroup {
ContentView(appState: appState)
}
}
}
景色:
struct ContentView: View {
@State private var appState: AppState
init(appState: AppState) {
self.appState = appState
}
var body: some View {
VStack {
Text("first Count: \(appState.firstCount)")
Text("Result Count: \(appState.resultCount)")
Button {
appState.firstCount += 1
} label: {
Text("Plus")
}
}
}
}
每次通过
resultCount
更新 firstCount
时,都应更新 Button
。
我猜 Cancellables 必须在 View 层次结构中创建,但我并不真正理解它是如何工作的。
如果我在
CurrentValueSubject
内设置 View
,它会起作用:
执行
Updater
设置的视图:
struct ContentView: View {
@State private var appState: AppState
init(appState: AppState, updater: Updater) {
self.appState = appState
updater.setup(appState: appState)
}
//...
}
App
结构将 Updater
的实例传递给 View
:
@main
struct TestCombineInViewApp: App {
var appState: AppState = AppState()
private var updater = Updater()
var body: some Scene {
WindowGroup {
ContentView(appState: appState, updater: updater)
}
}
}
只是不确定代码的哪一部分“安装”在
View
上以获取更新。