从另一个对象观察@Published var

Pet*_*ter 5 swift combine

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

\n
class Model : ObservableObject{\n    @Published var items: [Int] = []\n}\n\nclass ObjectUsingItems{\n    var itemObserver: AnyCancellable?\n    var items: [Int] = []\n    \n    func observeItems(model: Model){\n        itemObserver = model.$items\n            .sink{ newItems in\n                self.items = newItems\n                print("New Items")\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
let model = Model()\nlet itemUser = ObjectUsingItems()\n        \nitemUser.observeItems(model: model)\nmodel.items.append(1) // itemUser sees changes\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
class ObjectUsingItems{\n    var itemObserver: AnyCancellable?\n    var items: [Int] = []\n    \n    func observeItems(propertyToObserve: WhatGoesHere?){\n        itemObserver = propertyToObserve\n            .sink{ newItems in\n                // etc.\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后这样称呼它:

\n
itemUser.observeItems(XXX: model.$items)\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

New*_*Dev 3

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

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

func observeItems(propertyToObserve: Published<[Int]>.Publisher) {
   itemObserver = propertyToObserve
                     .sink { self.items = $0 }
}
Run Code Online (Sandbox Code Playgroud)

但这可能限制太多——为什么只有这个特定的出版商?原则上,您不应该关心发布者是什么 - 您只关心输出值和错误类型。您可以使其对任何发布者通用,只要其输出为[Int]且失败为Never(与该发布者相同@Published):

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

   itemObserver = propertyToObserve
                     .sink { self.items = $0 }
} 
Run Code Online (Sandbox Code Playgroud)

用法是这样的:

let model = Model()
let itemUser = ObjectUsingItems()
        
itemUser.observeItems(propertyToObserve: model.$items)
Run Code Online (Sandbox Code Playgroud)