Roobiq / RBQFetchedResultsController

Drop-in replacement for NSFetchedResultsController backed by Realm.
MIT License
476 stars 70 forks source link

RBQFetchedResults controller is returning nil #49

Closed beloso closed 8 years ago

beloso commented 8 years ago

Hi,

I am experiencing an issue, where the FRC is returning nil when calling objectAtIndexPath:

I reproduce this when sending a new item to Realm and notifying the FRC and at the same time scrolling a collection view.

I think it is related to querying realm in the main thread which is doing a lot of UI work, which causes realm to return nil. This is prolly a realm problem though.

https://github.com/realm/realm-cocoa/issues/2795

bigfish24 commented 8 years ago

(Reposting from the realm-cocoa thread...):

I would suggest you look at the implementation for ABFRealmGridController because this is a UICollectionViewController subclass that is using RBQFRC as its backing data source. It automatically updates based on results from the New York Times API and animates the changes... I have never encountered the scenario you describe.

bigfish24 commented 8 years ago

The issue was related to how Realm notifies other Realm instances to update. When you commit a write transaction on a background thread, a notification is then sent to other Realm instances on other threads (this works through a named pipe) to refresh to the latest version of the DB that includes the recently committed transaction. The problem though is that notification is processed on the receiving thread only during the default run loop mode. When you are scrolling, the main thread will run in NSEventTrackingRunLoopMode for that pass of the run loop. This means that Realm's notification will not be processed until the thread is back in default mode.

The result of this means that RBQFetchedResultsController should simply manually call refresh on the Realm that contains the objects backed by the FRC before attempting to retrieve it. This alleviates the assumption that the notification to trigger the refresh has been processed before object/safeObjectAtIndexPath: is called.

I can confirm this commit fixes the problem: https://github.com/Roobiq/RBQFetchedResultsController/commit/03de5b623e4451dede175c356826a2960d966664