2015-02-23 13 views
6

Tôi muốn tải xuống các thành phố (tên, id, lon, lat) từ tệp .json của tôi vào cơ sở dữ liệu Realm.Realm.io - Realm truy cập từ chủ đề không chính xác swift

Tôi đã tạo ra đối tượng Realm gọi là thành phố, nhưng nó bị treo với các lỗi sau:

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

Vì vậy, tôi chỉ muốn có được một đối tượng Realm trong self.cities ([City]) mảng của tôi. Sau đó đặt nó vào khung nhìn bảng.

chức năng làm mới của tôi:

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

} 

dịch vụ:

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

}

Và loadCities hoạt

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


} 

Trả lời

12

Trường hợp ngoại lệ là nói cho bạn biết chính xác những gì đang xảy ra - một RLMRealm trường hợp (và tất cả các đối tượng thu được từ nó) chỉ hợp lệ trên một sợi đơn. Mỗi lần bạn gửi hàng đợi riêng biệt, bạn sẽ cần phải tạo một phiên bản RLMRealm mới và tìm nạp lại RLMObject trước khi truy cập bất kỳ thuộc tính nào hoặc bắt đầu một giao dịch ghi mới.

+0

Cảm ơn bạn đã trả lời. Nhưng tôi chỉ sử dụng một hàng đợi và tôi chỉ muốn đặt tất cả dữ liệu trong mảng self.cities. Và khi nó được thực hiện - cập nhật một tableview. – Mazorati

+0

Một điều nữa - khi tôi làm tất cả mọi thứ mà không có chức năng async - công việc của nó, nhưng xem bảng cập nhật sau 2-3 phút và tải dữ liệu json trong 2 giây ... Vậy phần bên trái là dành cho lĩnh vực? – Mazorati

+1

Thậm chí nếu bạn chỉ sử dụng một hàng đợi, vì không có sự đảm bảo nào về luồng, một hàng đợi công văn sẽ gửi các hoạt động của nó lên, bạn vẫn phải nạp lại cõi mỗi khi bạn gửi đi. – segiddins

Các vấn đề liên quan