嘿,我正在尝试将RealmNotifications与更新tableView结合在一起,但是由于某些原因,由于存在的节数与领域通知已发送的内容不一致,因此在tableView上始终会产生多个崩溃。这是我用来观察Results<T>
上任何更改的代码:
do {
let realm = try Realm()
sections = realm.objects(AssetSections.self).filter("isEnabled = true AND (assets.@count > 0 OR isLoading = true OR banners.@count > 0 OR tag == 'My Tools')").sorted(byKeyPath: "sort_order", ascending: true)
guard let sections = sections else { return }
// Watch on the asset sections
notificationToken = sections.observe { [weak self] (change: RealmCollectionChange) in
switch change {
case .initial: break
case .error(let error):
self?.handle(error: error)
case .update(_, let deletions, let insertions, let modifications):
self?.updatedModel.onNext((insertions: insertions, modifications: modifications, deletions: deletions))
}
}
} catch { }
上面的代码发生在ViewModel上,并且ViewController正在观察这些变化,如下所示:
vm.updatedModel
.subscribe(onNext: { [weak self] (insertions, modifications, deletions) in
guard let `self` = self else { return }
self.tableView.beginUpdates()
self.tableView.insertSections(insertions, animationStyle: .none)
self.tableView.deleteSections(deletions, animationStyle: .none)
self.tableView.reloadSections(modifications, animationStyle: .none)
self.tableView.endUpdates()
})
.disposed(by: disposeBag)
我正在使用节而不是行,因为这是一个包含多个节的tableView,每个节只有一行。
我要崩溃的原因是,如果我执行一次刷新操作,它会进行多个网络调用,从而对对象进行了多次更改。有趣的是,如果我在拉动刷新时快速向下滚动,几乎总是可以复制崩溃。错误如下:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete section 14, but there are only 14 sections before the update'
我获得tableView的numberOfSections
的方式如下:
var numberOfSections: Int {
return sections?.count ?? 0
}
我的怀疑是,由于通知是在主线程的下一个runLoop上传递的,并且由于我在收到通知和tableView对其进行响应时通过滚动和弄乱UI使线程繁忙,它已经不同步了。但是我不确定这是问题还是解决方法。
谢谢
一种避免这种情况的方法是在.reloadData()
上仅使用tableView
,但这是性能上的成功,尤其是在大型数据集上,我无法使用默认的tableView动画。为了减少多次致电.reloadData()
所带来的影响,我正在使用debounce。
vm.updatedModel
.debounce(1.0, scheduler: MainScheduler.instance)
.subscribe(onNext: { [weak self] (insertions, modifications, deletions) in
guard let `self` = self else { return }
self.tableView.reloadData()
})
.disposed(by: disposeBag)
答案 0 :(得分:0)
一个好问题,看起来好像Realm文档确实和您一样(用行而不是节),但没有解决这个问题。我看不出明显的答案,但是我能做的最好的就是这些可能的解决方法(尽管tbh也不是很好)。
sections
的静态副本以在本地使用,并在订阅中更新它。也就是说,将RealmCollection复制到一个数组中,然后该数组不是该领域的动态视图。这将与您的更新保持同步。我能做到的。否则,我看不到如何保证动态查询和通知之间的同步。