2015-11-03 69 views
2

我有一個類Store,方法fetchProducts在後臺工作,並保存來自json數據的產品。關係線程中的核心數據保存對象

class Store: NSManagedObject { 

     func fetchProducts(q: String) { 
      .... 
      let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT 
      dispatch_async(dispatch_get_global_queue(priority, 0)) { 
       self.saveProduct(json_data) 
      } 
     } 
    } 

} 

在這個類我有一個方法saveProduct來檢查,如果產品存在,那麼這個產品應該是更新或創建新的:

func saveProduct(data:[String: String]) -> Bool { 
     var product:Product 
     var products = self.products.allObjects as! [Product] 
     if (self.managedObjectContext == nil) { 
      return false 
     } 

     if (data["storeName"] != nil) { 
      products = products.filter{ $0.storeName == data["storeName"] } 
    } else { 
     return false 
    } 

     let privateContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType) 
     privateContext.persistentStoreCoordinator = self.managedObjectContext!.persistentStoreCoordinator 

     if (data["storeName"] != nil) { 
      products = products.filter{ $0.storeName == data["storeName"] } 
     } else { 
      return false 
     } 
     if products.count > 0 { 
      product = products.first! 
     } else { 
      if let productEntity = NSEntityDescription.entityForName("Product", inManagedObjectContext: privateContext) { 
       product = Product(entity: productEntity, insertIntoManagedObjectContext: privateContext) 
      } else { 
       return false 
      } 
     } 

     product.setValue(data["storeName"], forKey: "storeName") 
     product.setValue(data["storeType"], forKey: "storeType") 
     product.setValue(self, forKey: "shopItem") 
     privateContext.performBlockAndWait { 
      do { 
       try privateContext.save() 
      } catch { 
       fatalError("Failure to save context: \(error)") 
      } 

     } 

     return true 
    } 

,但我得到的錯誤這條線:product.setValue(self, forKey: "shopItem")

非法嘗試建立在 不同的上下文對象之間的關係

如何保存產品的fk字段?

+1

請注意,您不應該在私有上下文中設置「persistenStoreCoordinator」(不建議使用)。相反,設置'parentContext'。 – Mundi

回答

2

如果您運行的是product = products.first!,那麼您使用的是與「self」相同的上下文中的原始產品。該上下文與privateContext不同,因此您的保存並不會實際上保留更改。

如果您運行的是product = Product(entity:...,那麼您在privateContext中使用的新產品與self的背景不同。

什麼,你真正應該做的是在當前線程上任何過濾和使用objectID查找在privateContext比賽,或者做一個過濾取上privateContext。通過這種方式,你總是有一個產品在privateContext。然後您需要使用self.objectIDprivateContext中獲得self,以便您可以更新關係並保存。

這是維持線程約束所需的全部。

事實上,你也應該運行這個是performBlock(或等待版本),以便上下文可以在其專用隊列中運行邏輯。