首页 > 解决方案 > 为什么 tableview 数据源不会从 Realm Collection 观察者改变?

问题描述

我有对领域数据库的请求

  func allContacts() -> Results<RMContact> {
    let realm = self.encryptedRealm()
    return realm!.objects(RMContact.self).sorted(byKeyPath: "lastActive", ascending: false)
}

和演示者的代码

        DispatchQueue.main.async {
        let contacts = RMContactsManager.shared.allContacts()
        self.notificationToken = contacts.observe { [weak self] (changes: RealmCollectionChange) in
            guard let tableView = self?.view.tableView else { return }
            switch changes {
            case .initial:
                UIView.performWithoutAnimation {
                    tableView.reloadData()
                }
            case .update(_, let deletions, let insertions, let modifications):
                UIView.performWithoutAnimation {
                    tableView.beginUpdates()
                    tableView.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }), with: .automatic)
                    tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}), with: .automatic)
                    tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }), with: .automatic)
                    tableView.endUpdates()
                }
            case .error(let error):
                fatalError("\(error)")
            }
        }
    }

在 tableview 中设置新的 lastActive 值序列后没有改变第一次对控制器进行实际排序,但在将新值设置为 lastActive 属性后没有变化。是观察者问题吗?

标签: iosswiftdatabaseuitableviewrealm

解决方案


问题似乎是您在插入、删除和修改方面发生了变化。

如果您将首先进行插入然后删除,(这就是您现在正在做的事情),它将插入新值并且数据源将被修改,所以现在当您删除行时,它将不正确。

同样在您对数组进行排序的情况下,通常会替换两个元素,一个被删除,另一个将被添加。

因此,可以解决您的问题的是,先进行删除,然后再进行插入。像这样:

UIView.performWithoutAnimation {
    tableView.beginUpdates()
    tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}), with: .automatic)
    tableView.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }), with: .automatic)
    tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }), with: .automatic)
    tableView.endUpdates()
}

推荐阅读