@Published 用于计算 属性 (或最佳解决方法)

@Published for a computed property (or best workaround)

我正在尝试使用 SwiftUI 构建应用程序,而我刚刚开始使用 Combine 框架。我的第一个简单问题是我想要一个定义应用程序何时正确初始化的变量。不过,我 喜欢 它由一些嵌套对象驱动。例如,在初始化帐户对象时初始化应用程序,初始化项目对象等。然后我的应用程序可以使用 GlobalAppState.isInitialized,而不是检查每个嵌套对象。

class GlobalAppState: ObservableObject {

    @Published var account: Account = Account()
    @Published var project: Project = Project()

    @Published var isInitialized: Bool {
        return self.account.initialized && self.project.initialized;
    }
}

我收到错误 Property wrapper cannot be applied to a computed property

所以...显然,目前不允许这样做。有什么办法可以解决这个问题吗???我希望能够在应用程序中使用 GlobalAppState.initialized 作为标志。更重要的是,像 GlobalAppState.project.currentProject 这样的东西是计算出来的 属性 返回当前选择的项目,等等...

我可以看到这种模式在上千个不同的地方被使用!任何帮助将不胜感激...

谢谢!

在这种情况下,没有理由对 isInialized 属性 使用 @Published,因为它派生自另外两个已发布的属性。

    var isInitialized: Bool {
        return self.account.initialized && self.project.initialized;
    }

如果accountproject都是结构体,这里是一种情况。

       struct Account{
            var initialized : Bool = false
        }

        struct Project{
            var initialized : Bool = false
        }

        class GlobalAppState: ObservableObject {

            @Published var account: Account = Account()
            @Published var project: Project = Project()
            @Published var isInitialized: Bool = false

             var cancellabel: AnyCancellable?

            init(){
                cancellabel =  Publishers.CombineLatest($account, $project).receive(on: RunLoop.main).map{
                           return ([=10=].0.initialized &&  [=10=].1.initialized)
                           }.eraseToAnyPublisher().assign(to: \GlobalAppState.isInitialized, on: self) as AnyCancellable
                }


        }


        struct GlobalAppStateView: View {

        @ObservedObject var globalAppState = GlobalAppState()

        var body: some View {
            Group{
              Text(String(globalAppState.isInitialized))
              Button(action: { self.globalAppState.account.initialized.toggle()}){ Text("toggle Account init")}
              Button(action: { self.globalAppState.project.initialized.toggle()}){Text("toggle Project init")}
            }
            }
        }