我有一个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字段?

最佳答案

如果您通过product = products.first!运行,那么您使用的是与“self”相同上下文的原始产品。该上下文与privateContext不同,因此您的保存实际上不会保留更改。

如果您通过product = Product(entity:...运行,则说明您在privateContext中使用的新产品与self的上下文不同。

您真正应该做的是在当前线程上进行过滤,并使用objectIDprivateContext中查找匹配项,或者对privateContext进行过滤后的提取。这样,您始终在privateContext中有一个产品。然后,您需要使用self.objectIDself中获取privateContext,以便您可以更新关系并保存。

这是维持线程限制所必需的。

实际上,您还应该运行performBlock(或等待版本),以便上下文可以在其专用队列中运行逻辑。

09-13 08:09