SwiftUI 视图中的 onReceive 导致无限循环

gna*_*ket 6 swiftui

在 SwiftUI 应用程序中,我有一个ObservableObject跟踪用户设置的应用程序:

class UserSettings: ObservableObject {
    @Published var setting: String?
}
Run Code Online (Sandbox Code Playgroud)

我有一个视图模型来控制视图的状态:

class TestViewModel: ObservableObject {
    @Published var state: String = ""
}
Run Code Online (Sandbox Code Playgroud)

我有我的看法。当用户设置更改时,我想让视图模型更新视图的状态:

struct HomeView: View {
    @EnvironmentObject var userSettings: UserSettings
    @ObservedObject var viewModel = TestViewModel()

    var body: some View {
        Text(viewModel.state)
            .onReceive(userSettings.$setting) { setting in
                self.viewModel.state = setting
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

UserSettings.setting在另一个视图中更改时,它会导致onReceive我的视​​图在无限循环中被调用,我不明白为什么。我看到了这个问题,这个循环对我来说很有意义,因为被ObservableObject观察者的状态正在随着观察而改变。

但是,就我而言,我不会更改观察到的对象(环境对象)状态。我正在观察环境对象并更改重绘视图的视图模型状态。

视图重绘是否导致了这里的问题?onReceive每次重绘视图时都会被调用吗?

有更好的方法来完成我想做的事情吗?

编辑:这是我的问题的一个大大简化的版本。在我的应用程序中,视图模型负责根据用户的设置执行网络请求并更新视图的状态,例如显示错误消息或加载指示器。

sma*_*kus 5

每当您有一个带有 @ObservedObject 的 onReceive 来设置 @ObservedObject 的另一个(或相同)发布值时,如果这些发布的属性以某种方式显示,那么您就有创建无限循环的风险。

让你的 onReceive 验证接收到的值实际上是在更新一个值,而不仅仅是设置相同的值,否则它将无限地设置/重绘。在这种情况下,例如:

.onReceive(userSettings.$setting) { setting in
          if setting != self.viewModel.state {
            self.viewModel.state = setting
          }
      }
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你!!!这实际上是唯一能让我的代码正常工作的东西。你是一个传奇!! (2认同)

Asp*_*eri 2

从描述的场景来看,我没有看到在视图模型中重复设置的原因。您可以直接显示来自 的值userSettings,如

struct HomeView: View {
    @EnvironmentObject var userSettings: UserSettings
    @ObservedObject var viewModel = TestViewModel()

    var body: some View {
        Text(userSettings.setting)
    }
}
Run Code Online (Sandbox Code Playgroud)