gpt4 book ai didi

swift - RealmSwift RealmCollectionChange tableView 崩溃

转载 作者:搜寻专家 更新时间:2023-10-31 23:06:09 25 4
gpt4 key购买 nike

嗨,我正在尝试将 RealmNotifications 与更新 tableView 相结合,但由于某些原因,由于存在的部分数量与 Realm 通知发送的内容不一致,这会不断在 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'

我得到 numberOfSections 的方式对于 tableView 如下:

var numberOfSections: Int {
return sections?.count ?? 0
}

我的怀疑是,因为通知是在主线程的下一个运行循环中传递的,并且因为在我收到通知并且 tableView 对其使用react时,我通过滚动和弄乱 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)

最佳答案

很好的问题,看起来 Realm 文档和您做的完全一样(使用行而不是部分),但没有解决这个问题。我看不到明显的答案,但我能做的最好的就是这些可能的解决方法(尽管说实话,两者都不是很好)。

  1. 重新编写更新代码以汇总结果,然后在完成后进行一次提交。
  2. 制作的静态副本以在本地使用,并在订阅中更新它。即,将 RealmCollection 复制到一个数组,这不是该 Realm 的动态 View 。这将与您的更新保持同步。

尽我所能。否则,我看不出你如何保证动态查询和通知之间的同步。

关于swift - RealmSwift RealmCollectionChange tableView 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54804235/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com