【问题标题】:What is the difference between @Published and normal AnyPublisher property in ObservableObjectObservableObject 中的@Published 和普通 AnyPublisher 属性有什么区别
【发布时间】:2020-03-06 09:19:57
【问题描述】:

我考虑有什么区别

@Published var isLoggedIn: Bool = false 

var isLoggedIn: AnyPublisher<Bool, Never> 

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

但是我怎样才能用AnyPublisher&lt;Bool, Never&gt; 达到同样的效果,看来我需要在某个地方调用 assignsinkstore()。让它发挥作用。所以在 SwiftUI 中创建绑定似乎是不可能的,就像if $isLoggedIn.animation

@Published 的限制是我不能在那里进行自定义观察。例如,我可以通过 UserDefaults.publisher 中的 AnyPublisher 执行 UserDefaults。

现在看来我需要两者兼而有之并让AnyPublisher更新@Published var

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

【问题讨论】:

  • "...@Published 是我不能在那里进行自定义观察。"为什么不?它像任何其他主题一样具有发布者,您可以使用运算符、接收器……任何您需要的东西。

标签: swiftui combine


【解决方案1】:

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

@Published 属性也根本不像 AnyPublisher@Published 始终以 Never 作为其故障类型,AnyPublisher 可以有其他故障情况。

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

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

【讨论】:

  • 您似乎将 SwiftUI 与 Combine 混为一谈。 @Published 不是 SwiftUI 特定的属性包装器,它甚至不是框架的一部分。
  • 哎呀,你是对的。很容易将两者混为一谈。除了我回答中的第一个词之外,其余的都是准确的。我会更新,所以答案是正确的。
  • @donnywals 我是 Combine 的新手,并且正在努力理解如何将值分配给专用的 Published 属性。您能否提供一些示例代码来说明如何执行此操作?我特别尝试使用 combineLatest() 将两个 Published 值组合成一个新的 Published 值。提前致谢!
【解决方案2】:

自定义观察的示例用法

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

如果需要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-30
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    相关资源
    最近更新 更多