You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
let realm = try! Realm()
let laps = realm.objects(Lap.self)
Observable.changeset(from: laps)
.subscribe(onNext: { results, changes in
if let changes = changes {
// it's an update
print(results)
print("deleted: \(changes.deleted)")
print("inserted: \(changes.inserted)")
print("updated: \(changes.updated)")
} else {
// it's the initial data
print(results)
}
})
The above code sets synchronousStart to true by default.
Here is the implementation of Observable.changeset(from: synchronousStart):
public static func changeset(from collection: E, synchronousStart: Bool = true)
-> Observable<(AnyRealmCollection<E.ElementType>, RealmChangeset?)> {
return Observable.create { observer in
if synchronousStart {
observer.onNext((collection.toAnyCollection(), nil))
}
let token = collection.toAnyCollection().observe { changeset in
switch changeset {
case .initial(let value):
guard !synchronousStart else { return }
observer.onNext((value, nil))
case .update(let value, let deletes, let inserts, let updates):
observer.onNext((value, RealmChangeset(deleted: deletes, inserted: inserts, updated: updates)))
case .error(let error):
observer.onError(error)
return
}
}
return Disposables.create {
token.invalidate()
}
}
}
If the database is modified continuously from a background thread it can happen that the database changes in between invoking code observer.onNext((collection.toAnyCollection(), nil)) and guard !synchronousStart else { return }. As a result one change is swallowed and the next change that is delivered by observer.onNext((value, RealmChangeset(deleted: deletes, inserted: inserts, updated: updates))) will be incompatible with the previously saved state of the collection in the view model.
Because of the lost/swallowed change of the collection the incremental update of UITableView will crash the app if the change to be applied is not valid. (Invalid update, etc)
The current workaround for me is to set _ synchronousStart_ to false.
So, basically synchronous start with the current implementation does not work in some situation.
The text was updated successfully, but these errors were encountered:
JoeMatt
changed the title
Potential crash in UITableView when collection changes observed synchronously
[bug] Potential crash in UITableView when collection changes observed synchronously
Jan 22, 2022
Let's take the sample code from the readme:
The above code sets synchronousStart to true by default.
Here is the implementation of
Observable.changeset(from: synchronousStart)
:If the database is modified continuously from a background thread it can happen that the database changes in between invoking code
observer.onNext((collection.toAnyCollection(), nil))
andguard !synchronousStart else { return }
. As a result one change is swallowed and the next change that is delivered byobserver.onNext((value, RealmChangeset(deleted: deletes, inserted: inserts, updated: updates)))
will be incompatible with the previously saved state of the collection in the view model.Because of the lost/swallowed change of the collection the incremental update of UITableView will crash the app if the change to be applied is not valid. (Invalid update, etc)
The current workaround for me is to set _ synchronousStart_ to false.
So, basically synchronous start with the current implementation does not work in some situation.
The text was updated successfully, but these errors were encountered: