RxSwift RxRealm RxCocoa вставить строки в UITableView

#swift #realm #rx-swift #rx-cocoa

#swift #область #rx-swift #rx-cocoa

Вопрос:

Когда я просматриваю свою модель realm и привязываю изменения к табличному представлению, это работает. Но когда я пытаюсь добавить строку в таблицу, у меня происходит сбой

Завершение работы приложения из-за неперехваченного исключения ‘NSInternalInconsistencyException’, причина: ‘попытка вставить строку 1 в раздел 0, но после обновления в разделе 0 осталась только 1 строка’

Могу ли я сделать это без использования стандартных методов делегирования?

Вот мой фрагмент кода

         let realm = try! Realm()

    let places = realm.objects(Place.self)

    Observable.from(places)
        .bindTo(tableView.rx.items(cellIdentifier: "PlaceCell", cellType: PlaceCell.self)) { (row, element, cell) in
            let viewModel = PlaceCellViewModel(place: element)
            cell.setup(viewModel: viewModel)
        }
        .addDisposableTo(disposeBag)

    Observable.changesetFrom(places).subscribe(onNext: { [weak self] result, changes in

        if let changes = changes {
            self?.tableView.beginUpdates()
            let indexes = changes.inserted.map { IndexPath(row: $0, section: 0) }
            self?.tableView.insertRows(at: indexes, with: .bottom)
            self?.tableView.endUpdates()
        } else {
            self?.tableView.reloadData()
        }

        })
        .addDisposableTo(disposeBag)
  

Ответ №1:

В настоящее время у вас есть две подписки, конкурирующие друг с другом для обновления вашей таблицы.

  1. Ваша первая подписка использует привязку к вашему табличному представлению (в основном вызывается reloadData() каждый раз, когда происходят изменения в ваших базовых данных)

  2. Ваша вторая подписка также обновляет вашу таблицу, но на этот раз в ней используются детализированные методы вставки записей.

Следовательно, когда запускается вторая подписка — ваша первая подписка уже обновила вашу таблицу, и вы получаете сообщение о сбое. Сообщение об ошибке.


В настоящее время в RxRealm нет оболочки для переноса детализированных уведомлений в связующее (хотя вы можете создать проблему в репозитории RxRealm по этому поводу!)

Если вы хотите анимировать изменения для строк вашей таблицы, вы должны реализовать методы источника данных табличного представления, как здесь:

https://github.com/RxSwiftCommunity/RxRealm/blob/master/Example/RxRealm/ViewController.swift#L74


Обновление # 1: Я хотел бы добавить, что через некоторое время после этого (и других подобных вопросов) Я запустил RxRealmDataSources библиотеку, которая работает почти так же, как библиотека vanilla RxDataSources , но специально для размещения типов областей привязки. Библиотека заботится о том, чтобы привязать наблюдаемый RxRealm к представлению таблицы или коллекции как на iOS, так и на macOS и обновить их необходимыми анимациями.

Вот репозиторий GitHub: https://github.com/RxSwiftCommunity/RxRealmDataSources