首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Combine:监听内部集合变化

问Combine:监听内部集合变化
EN

Stack Overflow用户
提问于 2019-07-15 00:15:08
回答 2查看 2.1K关注 0票数 1

我有一个封装对象集合的数据管理器。我希望监听该管理器中的更改,以及集合对象中的更改。我想出了使用PassthroughSubject和sink的解决方案,但我是个新手,我想知道它是正确的,有没有更好的方法。

代码语言:javascript
复制
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    
EN

回答 2

Stack Overflow用户

发布于 2019-07-18 04:06:11

如果你可以控制存储的项目,那么让它们成为所有的结构应该是可行的。数组是结构,因此在更改时将触发didSet。数组中的结构应该更改数组的值,并导致数组的didSet触发。类将不会更改,因为该类的引用值永远不会更改。目前的立场是,除非有充分的理由使用类,否则应该使用结构而不是类。Swift documentation获取更多信息。

另一种选择是做您已经在做的事情,使所有类都符合某种协议,比如BindableObject,然后监视每个对象的didChange。

目前,虽然您没有在从数组中删除项目时处理取消。您应该将DataManager的 didChange

subscribe到每个元素的didChange。然后获取结果AnyCancellable并将其添加到该项目下键入的字典中。然后,一旦从数组中删除该项目,您应该删除关联的 AnyCancellable,这将取消订阅。

票数 1
EN

Stack Overflow用户

发布于 2019-09-30 15:58:39

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

下面是一个例子:

代码语言:javascript
复制
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发生更改,视图就会更新。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57029093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档