【问题标题】:Swift Combine Framework - How to properly observe an array?Swift Combine Framework - 如何正确观察数组?
【发布时间】:2023-11-02 09:03:01
【问题描述】:

假设我有一个 Person 结构数组,如下所示:

struct Person {
    var name: String
}

var persons = [Person(name: "A"), Person(name: "B"), Person(name: "C")]

let publisher = CurrentValueSubject<[Person], Never>(persons)

// subscribe to changes to the array
let subscription: AnyCancellable = publisher.sink { (persons) in
    print("The array has changed")
}

var currentPersons = publisher.value
currentPersons[0].name = "Changed"
publisher.send(currentPersons)

这行得通。每当数组中的任何内容发生更改或删除或添加内容时,它都会发布。

但是,如果我还想另外订阅数组中的一个元素怎么办?我可以这样做吗?我就是想不通。

【问题讨论】:

  • 通过将Person 的属性公开为CurrentValueSubjects,使Person 可观察
  • 我试过了,但效果不佳。我总是拥有persons 数组的多个副本,而不是跟踪它的一个实例
  • 将您的数组包装成Contacts 对象或其他任何东西,并使其成为数组的唯一所有者。

标签: swift combine


【解决方案1】:

在数组中引用并不会神奇地将对象置于观察之下。如果你想观察一个物体,你必须观察那个物体本身。使这些观察与某个数组的内容保持一致是非常棘手的,因为您需要在添加新对象时开始观察它,并在删除时停止观察它。

【讨论】:

  • 这就是我所担心的。我只是希望有一个简单的方法来做到这一点。我已经玩了整整四天而没有让它工作。在这一点上,我考虑回到使用类作为数据模型(我切换是因为我读到的结构更适合这个)。跟踪更改在课堂上需要做更多的工作,但做这些事情似乎更容易,而且不会导致数据的多个副本不同步。
  • 嗯,这不是一个新问题。多年来,人们一直在用 KVO 做这件事。有关典型方法,请参阅 github.com/MaxGabriel/NSArrayKVO。您可以将其调整为 Combine(毕竟可以使用 KVO)。