Realm.io - Realm accessed from incorrect thread swift

10,923

The exception is telling you exactly what's going on -- an RLMRealm instances (and all the objects obtained from it) are only valid on a single thread. Every time you dispatch onto a separate queue, you'll need to create a new RLMRealm instance and re-fetch your RLMObjects before accessing any properties or starting a new write transaction.

Share:
10,923
mazy
Author by

mazy

Updated on June 14, 2022

Comments

  • mazy
    mazy almost 2 years

    I want to download cities (name,id,lon,lat) from my .json file to Realm database.

    I have created Realm object called City, but it crashes with the following error:

    Terminating app due to uncaught exception 'RLMException', reason: 'Realm accessed from incorrect thread'** 
    

    So, I just want to get a Realm objects in my self.cities ([City]) array. Then to put it in the table view.

    My refresh function:

    func refresh(sender:AnyObject)
    {
    
            var service = CityService()
    
            service.getCities {
                (response) in
    
                if(response.count > 0){
                    if(response["cities"] != nil){
                        self.citiesStore.loadCities(response["cities"]! as NSArray,tableView: self.tableView)
                        self.tableView.reloadData()
                    } else {
                        println("No response data")
                    }
                }
    
    }
    

    Service:

    class CityService {
    var getCityUrl = "http://test:8888/cities.json";
    
    func getCities(callback:(NSDictionary)->()) {
        get(getCityUrl,callback:callback)
    }
    
    func get(url:String, callback:(NSDictionary) -> ()){
        var nsURL = NSURL(string: url)
    
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    
        let task = NSURLSession.sharedSession().dataTaskWithURL(nsURL!) {
            (data,response,error) in
            var error: NSError?
    
            UIApplication.sharedApplication().networkActivityIndicatorVisible = false
    
            if(error == nil){
                if(response != nil){
                    var response = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
                    callback(response)
                } else {
                    callback(NSDictionary())
                }
            }
    
        }
    
        task.resume()
    }
    

    }

    And loadCities function

    func loadCities(citiesJson:NSArray,tableView: UITableView) {
    
        var realmQueue = dispatch_queue_create("db", DISPATCH_QUEUE_SERIAL)
    
        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_async(realmQueue) {
            println("start")
    
            var cc:[City] = []
    
    
            var realm = RLMRealm.defaultRealm()
    
            realm.beginWriteTransaction()
    
            for object in citiesJson {
    
                City.createOrUpdateInRealm(realm, withObject: object)
    
            }
    
            realm.commitWriteTransaction()
    
            let citiesFromRealm = City.allObjects()
    
            for object in citiesFromRealm {
                let cityObject = object as City
    
                //println(cityObject.name)  <-- here ok
    
                cc.append(cityObject)
            }
    
            println("point")
    
            dispatch_async(dispatch_get_main_queue()) {
                println("ok")
                self.cities.removeAll(keepCapacity: false)
                self.cities = cc
    
                println(self.cities[3].name) // <--- Here an error
    
                tableView.reloadData()
            }
        }
    
    
    }