从另一个对象观察 @Published 变量

Posted

技术标签:

【中文标题】从另一个对象观察 @Published 变量【英文标题】:Observing a @Published var from another Object 【发布时间】:2020-08-19 03:05:55 【问题描述】:

我试图让一个对象监听另一个对象的属性变化。我让它按如下所示工作,但我希望观察对象对模型一无所知,只知道属性。

class Model : ObservableObject
    @Published var items: [Int] = []


class ObjectUsingItems
    var itemObserver: AnyCancellable?
    var items: [Int] = []
    
    func observeItems(model: Model)
        itemObserver = model.$items
            .sink newItems in
                self.items = newItems
                print("New Items")
        
    

目前我开始观察 model.items 如下 - 这很有效:

let model = Model()
let itemUser = ObjectUsingItems()
        
itemUser.observeItems(model: model)
model.items.append(1) // itemUser sees changes

不幸的是,我似乎无法弄清楚 observeItems 方法的参数需要什么,以便它在不了解模型的情况下工作 - 像这样:

class ObjectUsingItems
    var itemObserver: AnyCancellable?
    var items: [Int] = []
    
    func observeItems(propertyToObserve: WhatGoesHere?)
        itemObserver = propertyToObserve
            .sink newItems in
                // etc.
        
    

然后这样称呼它:

itemUser.observeItems(XXX: model.$items)

谁能解释我需要做什么?谢谢!

【问题讨论】:

【参考方案1】:

如果您不关心值的来源,您可以只接受发布者作为参数。

在您非常具体的情况下,可能是:

func observeItems(propertyToObserve: Published<[Int]>.Publisher) 
   itemObserver = propertyToObserve
                     .sink  self.items = $0 

但这可能过于严格 - 为什么只有这个特定的发布者?原则上,你不应该关心发布者是什么——你只关心输出值和错误类型。您可以使其对任何发布者通用,只要它的输出是[Int] 并且失败是Never(就像@Published 一样):

func observeItems<P: Publisher>(propertyToObserve: P) 
   where P.Output == [Int], P.Failure == Never 

   itemObserver = propertyToObserve
                     .sink  self.items = $0 
 

用法是这样的:

let model = Model()
let itemUser = ObjectUsingItems()
        
itemUser.observeItems(propertyToObserve: model.$items)

【讨论】:

非常感谢新开发者 - 完美运行,我永远也想不通。

以上是关于从另一个对象观察 @Published 变量的主要内容,如果未能解决你的问题,请参考以下文章

当从另一个 ObservedObject 链接到 Published 属性时,视图不会对更改做出反应

为啥可观察对象中的更新变量不会更新视图?

如何从另一个变量<[Team]> 观察变量<[Game]>?

SwiftUI 从另一个视图更改观察到的对象

如何根据从另一个可观察对象返回的数组中的键创建可观察/ http请求数组

类 Observable 对象 @Published 变量始终为空