当“changesetPublisher”发出集合变更集时不更新视图

Not update View when `changesetPublisher` emits a collection changeset

如果我在 Realm 模型 let book = List<Book>() 中有一个 属性,那么它的更改不会更新视图。

I think it`s because realm models are classes.

关于如何解决这个问题的任何想法

final class Book: Object, ObjectKeyIdentifable {

    @objc dynamic var id: String = ""
    @objc dynamic var title: String = ""
    @objc dynamic var subTitle: String = ""

    override class func primaryKey() -> String? {
        return "id"
    }
}

final class Author: Object, ObjectKeyIdentifable {

    @objc dynamic var id: String = ""
    @objc dynamic var name: String = ""
    let book = List<Book>()

    override class func primaryKey() -> String? {
        return "id"
    }
}

class Store: ObservableObject {

    @Published var Authors: Results<Author>?
    private var subscriptions = Set<AnyCancellable>()

    init() {
        let realm = try! Realm()
        realm.objects(Author.self)
            .changesetPublisher
            .sink { changeset in
                self.applyChangeset(changeset)
        }
        .store(in: &subscriptions)
    }

    func applyChangeset(_ changes: RealmCollectionChange<Results<Author>>) {
        switch changes {
        case .initial(let results):
            self.Authors = results
        case .update(let results, deletions: _, insertions: _, modifications: _):
            self.Authors = results
        case .error(let error):
            print(error.localizedDescription)
        }
    }
}

尝试在主队列上调度,因为

realm.objects(Author.self)
    .receive(on: DispatchQueue.main)      // << here !!
    .changesetPublisher
    .sink { [weak self] changeset in
        self?.applyChangeset(changeset)    // avoid cross reference
}

并明确通知更改,因为您使用的是引用类型模型,因此更改内部结构不会更改引用本身...所以

func applyChangeset(_ changes: RealmCollectionChange<Results<Author>>) {
    switch changes {
    case .initial(let results):
        self.Authors = results
    case .update(let results, deletions: _, insertions: _, modifications: _):
        self.Authors = results
        // let assume we consider this case, then
        self.objectWillChange.send()                // << this !!
    case .error(let error):
        print(error.localizedDescription)
    }
}