【问题标题】:Be Notified of Multiple ObservableObject Property Changes in Combine在组合中收到多个 ObservableObject 属性更改的通知
【发布时间】:2021-02-19 04:47:20
【问题描述】:

我有一个 Swift Combine 问题。假设我有一个ObservableObject,它有一些这样的属性:

class AppState: ObservableObject{
  static let shared = AppState()
  @Published var a: Object?
  @Published var b: Object?
  @Published var c = [Object]()
}

我知道如果单个对象发生如下变化,我会收到通知:

myCancellable = AppState.shared.$a.sink { a in
  //Object 'a' changed
}

但是有没有办法观察多个属性并在其中任何一个发生变化时做出响应?

类似:

myCancellable = AppState.shared.[$a, $b, $c].sink { a, b, c in
  //Objects 'a', 'b', or 'c' changed
}

【问题讨论】:

    标签: swift swiftui combine


    【解决方案1】:

    可能的变体是观察整个对象的任何已发布更改,例如

    myCancellable = AppState.shared
        .objectWillChange.sink {
           // react here
        }
    

    【讨论】:

      【解决方案2】:

      假设abc 是同一类型(Asperi 向我指出它们不在示例中,因为c 是一个数组),您可以使用Publishers.MergeMany

      myCancellable = Publishers.MergeMany([$a,$b,$c]).sink { newValue in 
      
      }
      

      对于一组参数,此函数还有更具体的版本。例如,在您的情况下,您可以使用 Publishers.Merge3

      通常,在我在网上看到的示例中,您会看到Publishers.MergeMany 后跟collect(),它会在继续之前收集所有发布者的结果,将结果作为数组发布。不过,从您的问题来看,这听起来并不能满足您的需求,因为您希望每次单个成员更改时都会收到通知。

      【讨论】:

      • MergeMany 适用于一种类型,但 c 是主题启动问题中的数组,因此无法编译。
      • 啊——好点子。错过了那个细节。编辑帖子以反映这一点。
      【解决方案3】:

      感谢您的精彩回答。我偶然发现的另一个想法是将我的对象存储在 struct 中并观察它。

      struct Stuff{
        var a: Object?
        var b: Object?
        var c = [Object]()
      }
      

      然后在我的AppState 班级:

      class AppState: ObservableObject{
        static let shared = AppState()
      
        @Published var stuff: Stuff!
      }
      

      然后在发布者中:

      myCancellable = AppState.shared.$stuff.sink { stuff in
        print(stuff.a)
        print(stuff.b)
        print(stuff.c)
      }
      

      我喜欢这种方法,因为我不想观察AppState 类中可能发生的所有变化(这可能表明我应该将其分解成更小的部分)。到目前为止,这似乎运作良好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-24
        • 2016-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多