I'm adding this extension toRealm to avoid creating a Realm objects, but I'm not sure if this way is the good to use. Would you please tell me If it's ok or not?
import RealmSwift
extension Realm {
class var sharedRealm: Realm {
var realm = NSThread.currentThread().threadDictionary["sharedRealm"] as? Realm
if realm == nil {
realm = try! Realm()
NSThread.currentThread().threadDictionary["sharedRealm"] = realm
}
return realm!
}
}
and the way I call it is always.
Realm.sharedRealm
every where in my code. there is no other try! Realm() in my project but the one here.
No, that is not a good idea.
The simplest reason is because Realm already caches Realm instances per thread, so adding your own caching on top of that isn't doing anything functionally useful, and isn't even making your code using Realm any more concise.
The bigger problem is that this'll behave very poorly when used on background threads with GCD. Autorefresh only works on threads which are running inside a runloop (normally just the main thread), so the Realm instances on background threads will not be automatically updated to pull in changes made on other threads. Normally this is not a problem, because the instances on background threads are only live for the duration of a single dispatch block, and then the next block dispatched gets a fresh instance with the newest data.
Even if you manually call refresh() on a regular basis to ensure you're working with the latest data, the instances on other threads which have not yet been refreshed will force Realm to keep the data around for the versions they're using, resulting in the Realm file taking up much more space on disk.
That was a great information, which explains why some times I don't get updates happened in in background thread in the main one. Thanks.
@tgoyne or someone else from Realm -- is the above still true in Realm v3.7.2? Is it still a bad idea to hold a Realm in threadDictionary (in the sense that refreshes won't work, etc)?
How about holding a single Realm and only ever accessing it using a single DispatchQueue?
Nothing significant has changed with our threading model.
@tgoyne thanks. I'm only considering this because my customers report something that looks like #5138. In my use of Realm, I create a lot of Realm references. As much as about 100 per second.
I considered filing a bug report (or reviving the old one), but instead I'm trying to look for ways to reduce Realm ref creation.
Should I open a bug? I asked SO about best practice, but so far only got downvotes.
Most helpful comment
No, that is not a good idea.
The simplest reason is because Realm already caches Realm instances per thread, so adding your own caching on top of that isn't doing anything functionally useful, and isn't even making your code using Realm any more concise.
The bigger problem is that this'll behave very poorly when used on background threads with GCD. Autorefresh only works on threads which are running inside a runloop (normally just the main thread), so the Realm instances on background threads will not be automatically updated to pull in changes made on other threads. Normally this is not a problem, because the instances on background threads are only live for the duration of a single dispatch block, and then the next block dispatched gets a fresh instance with the newest data.
Even if you manually call
refresh()on a regular basis to ensure you're working with the latest data, the instances on other threads which have not yet been refreshed will force Realm to keep the data around for the versions they're using, resulting in the Realm file taking up much more space on disk.