ObservableObject中的@Published和普通的AnyPublisher 属性有什么区别

What is the difference between @Published and normal AnyPublisher property in ObservableObject

我考虑有什么区别

@Published var isLoggedIn: Bool = false 

var isLoggedIn: AnyPublisher<Bool, Never> 

我知道在第一种情况下,我可以直接在 SwiftUI 视图中使用它,即使用 $ 符号创建绑定,然后使用 if $isLoggedIn.animation()

但是我怎样才能用 AnyPublisher<Bool, Never> 实现同样的效果,我似乎需要在某个地方调用 assignsinkstore()。让它发挥作用。所以在 SwiftUI 中从它创建绑定似乎是不可能的 if $isLoggedIn.animation

@Published 的局限性在于我无法自定义观察。例如 UserDefaults,我可以通过 UserDefaults.publisher.

中的 AnyPublisher 完成

现在看来我需要同时拥有两者并进行 AnyPublisher 更新 @Published var

但我认为 @Published 是 属性 包装器,在常规 AnyPublisher 之下,所以为什么我不能直接从 AnyPublisher 在 SwiftUI 视图中进行绑定?

自定义观察的用法示例

import SwiftUI
import Combine

class Model: ObservableObject {
    @Published var flag = false
}


struct ContentView: View {
    @ObservedObject var model: Model
    let handle: AnyCancellable?
    init() {
        let m = Model()
        handle = m.$flag.sink(receiveValue: { (b) in
            print("model flag changed to:", b)
        })
        model = m
    }
    var body: some View {
        Toggle(isOn: $model.flag) {
            Text("Toggle")
        }.padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

从 SwiftUI.View 可以访问发布者

$model.$flag

如果需要。

Combine 的 @Published 是一个由 属性 包装器包装的发布者。这为它提供了 $ 前缀 属性 和 SwiftUI 工作所依赖的其他功能。

@Published 属性 也根本不像 AnyPublisher@Published 总是有 Never 作为它的失败类型,AnyPublisher 可以有其他失败案例。

@Published 具有状态感/当前值,而 AnyPublisher 并非如此。 CurrentValueSubject 会最接近,但这行不通,因为 @Published 可以用作绑定,而这对 CurrentValueSubject 是不可能的。一个重要的区别是 SwiftUI 可以直接将新值分配给 @Published 属性(isLoggedIn = true 会在此处触发更改)。

要在 SwiftUI 中与您的发布商合作,您需要将他们的值分配给专用 @Published 属性,正如您在原始问题中提到的那样。