1

我有一个封装对象集合的数据管理器。我想听听那个经理的变化,以及集合对象的变化。PassthroughSubject我使用and提出了解决方案sink,但我对 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    
4

2 回答 2

1

如果您可以控制存储的项目,则使它们成为所有结构都应该起作用。数组是结构体,因此在更改时会触发 didSet。数组内部的结构应该改变数组的值并导致 didSet 为数组触发。类不会因为类的引用值永远不会改变。当前的立场是,除非您有充分的理由使用类,否则您应该使用结构而不是类。Swift文档以获取更多信息。

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

目前,虽然您没有在从数组中删除项目时处理取消。你应该对subscribe每个元素的didChange。然后获取结果并将其添加到该项目下键入的字典中。然后,一旦从数组中删除该项目,您应该删除关联的,这将取消订阅。DataManagerdidChangeAnyCancellableAnyCancellable

于 2019-07-17T20:06:10.663 回答
1

对于最新版本的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
    }
}

使用此方法,只要数组中的 a 发生更改User,视图就会更新。users

于 2019-09-30T07:58:38.543 回答