2015-02-23 4 views
6

Я хочу загрузить города (имя, id, lon, lat) из моего .json файла в базу данных Realm.Realm.io - Realm, доступ к которому получен из неправильного потока swift

Я создал объект Realm под названием City, но он выходит из строя из-за ошибки:

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

Итак, я просто хочу, чтобы получить Realm объекты в моей self.cities ([City]) массива. Затем поместите его в таблицу.

Моя функция обновления:

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") 
       } 
      } 

} 

Услуги:

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() 
} 

}

И loadCities функционировать

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() 
     } 
    } 


} 

ответ

12

Исключение говорит вам именно то, что происходит - RLMRealm экземпляры (и все объекты, полученные из него) действительны только для одного потока. Каждый раз, когда вы отправляете отдельную очередь, вам нужно создать новый экземпляр RLMRealm и повторно получить свой RLMObject s перед доступом к любым свойствам или началом новой транзакции записи.

+0

Спасибо за ответ. Но я использую только одну очередь, и я просто хочу поместить все данные в массив self.cities. И когда это будет сделано - обновите таблицу. – Mazorati

+0

Еще одна вещь - когда я делаю все без функции async - ее работа, но обновление табличного представления через 2-3 минуты и загрузка данных json в течение 2 секунд ... Итак, левая часть для области? – Mazorati

+1

Даже если вы используете только одну очередь, так как нет никакой гарантии об этом потоке, диспетчерская очередь будет отправлять свои операции, вы все равно должны возвращать царство каждый раз при отправке. – segiddins

 Смежные вопросы

  • Нет связанных вопросов^_^