在视图之外初始化的组合函数

问题描述 投票:0回答:1

我有一个

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 层次结构中创建,但我并不真正理解它是如何工作的。

swift swiftui observable combine
1个回答
0
投票

如果我在

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
上以获取更新。

© www.soinside.com 2019 - 2024. All rights reserved.