组合:监听内部集合变化

Posted

技术标签:

【中文标题】组合:监听内部集合变化【英文标题】:Combine: Listen to internal collection changes 【发布时间】:2019-07-14 16:15:08 【问题描述】:

我有一个封装对象集合的数据管理器。我想听听那个经理的变化,以及集合对象的变化。我使用PassthroughSubjectsink 提出了解决方案,但我对Combine 很陌生,想知道它是否正确,是否有更好的方法来做到这一点。

import Combine

class Item 
  var data = false 
    didSet 
      self.subject.send()
    
  
  let subject = PassthroughSubject<Void, Never>()



class DataManager 
  private(set) var items = [Item]() 
    didSet 
      self.subject.send()
    
  
  let subject = PassthroughSubject<Void, Never>()

  func addItem(_ item: Item) 
    self.items.append(item)
    item.subject.sink  [weak self] in
      self?.subject.send()
    
  


var item = Item()
var manager = DataManager()
manager.subject.sink 
  print("Received Update")

manager.addItem(item) // Received Update
item.data = false // Received Update
item.data = true // Received Update    

【问题讨论】:

我也遇到了同样的问题,你有没有找到更好的方法? 【参考方案1】:

如果您可以控制存储的项目,则将它们设置为所有结构应该可以工作。数组是结构体,因此在更改时会触发 didSet。数组内部的结构应该改变数组的值并导致 didSet 为数组触发。类不会因为类的引用值永远不会改变。当前的立场是,除非您有充分的理由使用类,否则您应该在类上使用结构。斯威夫特documentation了解更多信息。

另一种选择是做你已经在做的事情,让所有的类都符合一些协议,比如BindableObject,然后监控每个对象的didChange

目前,尽管从数组中删除项目时您不处理取消。您应该将subscribe DataManagerdidChange 转换为每个元素的didChange。然后将生成的AnyCancellable 添加到该项目下键入的字典中。然后从数组中删除该项目后,您应该删除关联的AnyCancellable,这将取消订阅。

【讨论】:

【参考方案2】:

对于最新版本的SwiftUI,我会将objectWillChange.send 函数传递给@Published 数组中的每个项目。然后,对于每个项目的每个属性,我将在willSet 属性更改处理程序中调用更新处理程序。

这是一个例子:

import Combine

final class User 
    let prepareForUpdate: (() -> Void)?

    var name: String 
        willSet 
            prepareForUpdate?()
        
    

    init(prepareForUpdate: (() -> Void)? = nil, name: String) 
        self.prepareForUpdate = prepareForUpdate
        self.name = name
    


final class UserStore: ObservableObject 
    @Published var users: [User]

    init(_ users: [User] = []) 
        self.users = users
    

    func addUser(name: String) 
        // Pass in our objectWillChange.send to the User object to listen for updates
        let user = User(prepareForUpdate: objectWillChange.send, name: name)
        users.append(user)
        return user
    

使用此方法,每当users 数组中的User 发生更改时,视图都会更新。

【讨论】:

不确定这是不是最好的方法,在现实世界中,数据将来自后端,它如何与 Codable 一起工作?

以上是关于组合:监听内部集合变化的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 监听 MongoDB 变化

iOS 设计模式(五)-KVO 详解

在 Flutter 中监听 Firestore 集合及其子集合

java基础知识--- 集合类

Cloud Firestore 实时更新能否监听多个集合,即集合名称中有一个变量? [复制]

NodeJS 和 MongoDB:有没有办法监听集合并在集合有新文档时调用回调?