RxSwift + RxRealm + RxCocoa вставляет строки в UITableView

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

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

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

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

        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)

person milczi    schedule 22.10.2016    source источник


Ответы (1)


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

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

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

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


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

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

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


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

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

person Marin Todorov    schedule 25.10.2016