Search code examples
swiftrealmgrand-central-dispatch

Swift Error: Realm accessed from incorrect thread


I am attempting to use the Realm library to persist data within my application. However, I keep running into the same error code: "Realm accessed from incorrect thread". I attempted to resolve this issue by creating a Realm-specific Dispatch Queue, and wrapping all of my Realm calls in it.

Here is what my "RealmManager" class looks like right now:

import Foundation
import RealmSwift

class RealmManager {

fileprivate static let Instance : RealmManager = RealmManager()

fileprivate var _realmDB : Realm!
fileprivate var _realmQueue : DispatchQueue!

class func RealmQueue() -> DispatchQueue {
    return Instance._realmQueue
}

class func Setup() {
    Instance._realmQueue = DispatchQueue(label: "realm")
    Instance._realmQueue.async {
        do {
            Instance._realmDB = try Realm()
        } catch {
            print("Error connecting to Realm DB")
        }
    } 
}

class func saveObjectArray(_ objects: [Object]) {

    Instance._realmQueue.async {
        do {
            try Instance._realmDB.write {
                for obj in objects {
                    Instance._realmDB.add(obj, update: .all)
                }
            }
        } catch {
            print("Error Saving Objects")
        }
    }
}

class func fetch(_ type: Int) -> [Object] {

    if let realm = Instance._realmDB {
        let results = realm.objects(Squeak.self).filter("type = \(type)")
        var returnArray : [Object] = []
        for r in results {
            returnArray.append(r)
        }

        return returnArray
    }
    return []
}

I am calling Setup() inside of didFinishLaunchingWithOptions to instantiate the Realm queue and Realm Db instance.

I am getting the error code inside of saveObjectArray at:

try Instance._realmDB.write { }

This seems to simply be a matter of my misunderstanding of the threading requirements of Realm. I would appreciate any insight into the matter, or a direction to go in from here.


Solution

  • This issue is that you fetch your Realm data on a different thread than you save it.

    To fix the error, the code within fetch will also need to run on the Realm thread that you have created.

    I think this article does a good job of explaining multi-threading in Realm and particularly recommend paying attention to the three rules outlined in the article.