简体   繁体   English

RxSwift + RxRealm + RxCocoa将行插入UITableView

[英]RxSwift + RxRealm + RxCocoa insert rows to UITableView

When I observe my realm model and bind changes to table view it works. 当我观察我的领域模型并将更改绑定到表视图时,它就起作用了。 But when I try to add row to the table I have some crash 但是当我尝试向表中添加行时,我有些崩溃

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert row 1 into section 0, but there are only 1 rows in section 0 after the update' 由于未捕获的异常“ NSInternalInconsistencyException”而终止应用程序,原因:“试图将第1行插入第0节,但更新后第0节只有1行”

Can I do it without using standard delegates methods? 我可以不使用标准委托方法来做到吗?

Here is my code snippet 这是我的代码片段

        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)

Currently, you have two subscriptions racing against each other to update your table. 当前,您有两个订阅互相竞争以更新您的表。

  1. Your first subscription uses a binding to your table view (basically calling reloadData() each time there's a change in your underlying data) 您的第一个订阅使用到表视图的绑定reloadData()每次基础数据发生更改时,基本上都会调用reloadData()

  2. Your second subscription also updates your table but this time it uses the fine-grained methods to insert records. 您的第二个订阅也会更新您的表,但是这次它使用细粒度的方法来插入记录。

Hence when the second subscription kicks in - your first subscription has already updated your table and you get a crashing error message. 因此,当第二个订阅启动时-您的第一个订阅已经更新了您的表,并且您收到崩溃的错误消息。


Currently there's no wrapper in RxRealm to wrap fine-graned notifications in a binder (you can create an issue on the RxRealm repo about it though!) 当前,RxRealm中没有包装器,可以将细粒度的通知包装在活页夹中(不过您可以在RxRealm仓库中创建有关此问题的问题!)

If you'd like to have animated changes for your table rows you have to implement the table view data source methods, like here: 如果要对表行进行动画更改,则必须实现表视图数据源方法,例如:

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


Update #1: I'd like to add that some time after this (and other similar questions) I started an RxRealmDataSources library, which works pretty much like the vanilla RxDataSources library but specifically to accomodate for binding Realm types. 更新1:我想补充一点,在此之后(和其他类似的问题)有一段时间,我开始一个RxRealmDataSources库,它的工作原理非常像香草RxDataSources库,但专门以适应装订领域类型。 The lib takes care to bind an RxRealm observable to a table or collection view on both iOS and macOS and update them with the neccessary animations. 该库注意将可观察到的RxRealm绑定到iOS和macOS上的表或集合视图,并使用必要的动画对其进行更新。

Here's the GitHub repo: https://github.com/RxSwiftCommunity/RxRealmDataSources 这是GitHub存储库: https : //github.com/RxSwiftCommunity/RxRealmDataSources

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM