0
votes

It's not an issue, but rather just a general question on how realm collection change notifications are dispatched if changes happen in background thread.

So there is a scenario (in Realm Cocoa):

  1. RLMResults of objects of class Foo: RLMObject is fetched from default realm. The list is then transformed into array [Foo] and saved as variable in view controller (does not matter)
  2. Table displays that list of foo objects
  3. Some objects are deleted on background thread
  4. User scrolls the table view, cell is reused, object from array at index x is accessed, but it was deleted on background thread and crash happens, because object was deleted or invalidated. As expected.

To solve that we could use collection notifications and refresh the list when changes occur. As I tried everything works as expected, but isn't it possible that dispatch of cell reuse will occur before notification is dispatched on main thread so that cell setup method will be using invalidated object?

Just tried to explain the question as detailed as possible.

Mainly the question is about situation(s) when data sync with server (not using Realm's mobile platform) is happening on background thread and views, whether they're table cells or any other views, are holding references to could-be-deleted objects. Is it a good practice to check if object was invalidated when trying to do something with the object because it could be deleted on background thread.

I see a couple of solutions:

  • each time accessing reference of RLMObject subclass object check if it is not invalidated
  • wrap the object into view model (leaving all the good parts of self-updating model features) which then leaves with another two solutions when trying to change the model:
    • save object id in view model so that when trying to change it would be possible to fetch object again
    • have a reference to the object itself having the same problems as the first point

What are the suggestions for this?

EDIT:

Using Results and List sometimes not really possible if the object Foo is complicated. For example when opening details screen of Foo table view with lots of different cells accessing properties of Foo class' object. So on notification about deleted object screen could be dismissed, but as user scrolls isn't it possible that cell could be accessing invalidated object?

Maybe the question is just stupid, over engineered about raise conditions, but I'm curious if it's possible that dispatches on main thread will occur something like: object becomes invalidated (I don't know how that happens in realm internally> then some code which access that object then notification about invalidated object

1

1 Answers

0
votes

The list is then transformed into array [Foo] and saved as variable in view controller (does not matter)

Why do you do this? This forces every object in the Results to be materialized into memory, with (potentially expensive) Swift-level object accessors to be created and some db data read from disk. All Realm collections conform to the Swift standard library's CollectionType protocol, meaning that it behaves like other collections such as Array already. Copying out all of the Results elements into an Array will also mean that the array will quickly get out of sync with its underlying data, since Array isn't auto-updating unlike Results.

This easily explains why some of the Realm objects that you copy into the Array are then deleted, which causes the objects to become invalidated, meaning that any subsequent access is a violation of Realm's API.

Long story short, don't copy Results, List or any other Realm collection into an Array.