Hy, я пытаюсь связать 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'
Способ получения numberOfSections
для tableView следующий:
var numberOfSections: Int {
return sections?.count ?? 0
}
Я подозреваю, что, поскольку уведомления доставляются наследующий цикл выполнения основного потока, и поскольку я делаю поток занятым, прокручивая и связываясь с пользовательским интерфейсом к тому времени, когда я получаю уведомление, и tableView реагирует на него, он уже не синхронизирован.Но я не совсем уверен, если это проблема или как ее решить.
Спасибо
Редактировать
Один из способов избежать этого - просто .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)