RxSwiftCommunity / RxRealm

RxSwift extension for RealmSwift's types
MIT License
1.15k stars 263 forks source link

Realm.rx.delete() and Realm.rx.add() crash with same object #121

Closed micheltlutz closed 4 years ago

micheltlutz commented 5 years ago

Use case:

I have a favorite button, when it's favorited I press it again it changes to unfavorite and removes the record. When I re-favorite it it should insert the object again but it accuses this error below

Crash with error:

2019-02-20 09:58:44.348244-0300 Project[3851:768454] *** Terminating app due to uncaught exception 'RLMException', reason: 'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.'
*** First throw call stack:
(0x1babecec4 0x1b9dbda40 0x101681788 0x101683208 0x100565728 0x1006aea94 0x1006aeae4 
libc++abi.dylib: terminating with uncaught exception of type NSException
struct FavoriteTool {
    private let disposeBag = DisposeBag()
    var didLoadFavorites: (([Tool]) -> Void)?
private let disposeBag = DisposeBag()
    var didLoadFavorites: (([Tool]) -> Void)?
    func isFavorite(favoriteTool: FavoriteTool) -> Observable<Results<FavoriteTool>> {
        return favorites(filter: "id == '\(favoriteTool.id)'")
    }

    func favorite(favoriteTool: FavoriteTool) {
        if needSaveApi { saveApi(favoriteTool: favoriteTool) }
        Observable.just(favoriteTool)
            .subscribe(Realm.rx.add())
            .disposed(by: disposeBag)
    }

    func unfavorite(favoriteTool: FavoriteTool) {
        favorites(filter: "id == '\(favoriteTool.id)'")
            .subscribe(Realm.rx.delete())
            .dispose()
    }

    func favorites(filter predicateFormat: String? = nil) -> Observable<Results<FavoriteTool>> {
        guard let realm = try? Realm() else {
            return Observable.empty()
        }
        var results: Results<FavoriteTool> = realm.objects(FavoriteTool.self)
        if let predicate = predicateFormat {
            results = results.filter(predicate)
        }

        return Observable.collection(from: results)
    }
}
micheltlutz commented 5 years ago

Repo with problem:

https://github.com/micheltlutz/FavoriteRxRealm

M0rtyMerr commented 4 years ago

Hey @michaelavila thank you for reporting this.

I reviewed the provided repo, this error is not connected to RxRealm. It's caused by a little issue with Realm usage.

The point is - you can't modify objects, which were removed from Realm. Here is corresponding SO question - https://stackoverflow.com/questions/31852782/realm-object-has-been-deleted-or-invalidated

To make it work you need to create a new object and then add it to Realm.