phipsG phipsG - 1 year ago 180
Swift Question

Uncaught RLMException when accessing Realm from Singleton

This is not a duplicate question, please just continue reading!

I'm getting the "'RLMException', reason: 'Realm accessed from incorrect thread'" error message displayed when I use my

singleton in a DispatchQueue.

This is my class:

class RealmBackend {

static let shared = RealmBackend()
var realm = try? Realm()

There are functions in it like
which are accessing the
and the

Now I call the
function from a callback (
) with the
since I'm assuming the Realm object was created on the
Thread (I read somewhere on Github that you need the same Threads for instantiating and accessing the

As I stated before I always get this
, has someone faced the same problem?

Answer Source

Realm instances are thread confined, meaning that they will only work on the thread in which they were created. If you try and pass an instance between threads, you'll get that incorrect thread exception you saw. This is done by design to guarantee Realm's ACID compliance.

There's not really much point in holding onto a hard reference to Realm instances, especially in singleton objects. Once a Realm instance for a specific thread is created, Realm will internally hold onto that reference and will simply re-supply it if you try and create a new one with the same settings down the line. As a result, there's very little overhead in calling Realm() multiple times.

If you need to use a Realm instance with a different configuration than the default Realm, Configuration objects are thread safe, so you can simply store a single reference to that, and pass it to Realm() whenever you need it.

class RealmBackend {

    static let shared = RealmBackend()

    // A Configuration for a Realm in the caches directory
    let cacheConfiguration = Realm.Configuration(
                     fileURL: URL(fileURLWithPath: /* Path to the Realm in Caches */),
                     readOnly: true)

    func addObject() {
        let cacheRealm = try! Realm(configuration: cacheConfiguration)
        // ... add object to cacheRealm

    func getObject() -> Object {
        let cacheRealm = try! Realm(configuration: cacheConfiguration)
        let object = realm.objects(Object.self).first
        return object

In this case, since Realm is being created on demand, even if the singleton methods are being called on separate threads, Realm will internally be able to provide the correct instance.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download