Proper Realm usage patterns/best practices?
We're in the process of converting a project to use Realm. We're really impressed so far especially with the Realm Browser (so handy!).
As a result, a few questions have come up and we'd like to get some concrete usage patterns down before going any further. Our app is heavily multi threaded (API calls, animations, etc), so keep that in mind when reading the questions, since I know Realm instances cannot be accessed across threads (currently).
- How worried should we be about repeatedly creating instances of Realm? What is the overhead?
- Should we bother retaining Realm instances in ViewControllers or Singletons for repeated use? We've tried this but sometimes the instances are accessed from different threads, so we had to revert back to creating a new instance every time.
- When accessing relationship properties on Realm instances, is resulting data that is read retained in memory or is it read from disk every time? Do we have to worry about retained Realm instances becoming too large due to deep relationship access?
-
When is refreshing a Realm instance necessary? I've noticed that when I make changes in the Realm browser they are reflected in a retained Realm without calling refresh.- Looks like there's a Auto-Refresh property on each realm that causes this according to the documentation.
- Is accessing the
realm
property on anObject
bad practice? We've used this for writing to a Realm if the function using the object didn't create the object or the Realm (on the same thread of course).
For example...
func saveStuff(thingToUpdate: Object?) {
if let thingToUpdate = thingToUpdate, let realm = thingToUpdate.realm {
realm.write {
thingToUpdate.name = "lionpants"
}
}
}
Thanks in advance. I look forward to your answers. :D
(Disclaimer: I work for Realm. I've left Realm now, but I'm still happy to help!) :)
Thanks a lot! It's great to hear you're enjoying Realm!
Multiple Realm Instances - You don't need to worry about this at all! A Realm file object is created upon the first-time instantiation on each thread, and that same object is subsequently returned each time you try and instance it every time after that.
Retaining Realm Instances - Following on from the first point, no, you don't need to worry about hanging on to Realm reference inside other objects. As Realm tracks its Realm file objects internally and returns the same ones, you won't get penalised for not doing so. That being said, if having a permanent reference to a Realm object inside your object simplifies your code complexity, feel free to keep using it.
Accessing Realm Relationship Properties - Strictly speaking, data from Realm files aren't copied from disk (Like a normal ORM would do); more it uses memory mapping to directly reference the data from disk straight to your in-memory properties. So, no, you don't need to worry about Realm files getting too large in memory.
Auto-refresh
Auto-refresh is only enabled by default for the Realm file object on the main thread. It has to be manually enabled for Realm file objects on other threads, or you can instead elect to manually refresh them with the refresh
method call.
EDIT: I stand corrected! All Realm file objects on multiple threads have autorefresh
on by default. When autorefresh
is on, the only time you need to call refresh
is if you need the changes made to a Realm file to be reflected in the other references before the current iteration of the run loop has completed.
Referencing an object's Realm reference
Absolutely not, it's not bad practice at all! I actually prefer doing this in my own personal apps that use Realm to provide proper context since invariably it's easier, and provides stronger visual context between the object and its parent Realm file in the code. (Haha yep, if there was a threading problem here, you probably would have discovered it before even reaching the write
point).
I hope that helped! Let me know if you need clarification on anything here!