如何在Swift 4 CoreData

时间:2018-05-05 21:26:29

标签: ios swift core-data

我试图更新CoreData中的实体。以下是我的一些声明。

static var appDelegate = UIApplication.shared.delegate as! AppDelegate
static var context = appDelegate.persistentContainer.viewContext
static var entity = NSEntityDescription.entity(forEntityName: "PData", in: context)
static var newPData = NSManagedObject(entity: entity!, insertInto: context)

我确信他们的静态并不相关。

PData是实体的名称(持久数据的缩写)。

稍后,我设置了我想要使用newPData.setValue("foo", forKey: "bar")保存的值,但是当我实际尝试使用context.save()保存它们时,我得到NSCocoaErrorDomain Code 133020 "Could not merge changes."

我应该提一下,这是在删除PData中的现有条目后直接发生的(用新的实体替换旧的实体实例)。

我已经完成了一些阅读,并且我发现此错误的原因是Swift处理CoreData合并冲突的默认方式是抛出错误。我想更改我的CoreData设置,以便内存中的更改覆盖已存储在CoreData中的实体中的更改,但我不确定我将如何执行此操作。

Apple文档显示了许多不同的合并策略选项,但没有显示如何实现它们的示例。我认为我需要使用的是NSMergeByPropertyStoreTrumpMergePolicy,但我不知道如何将所述策略实际设置为合并策略。

3 个答案:

答案 0 :(得分:7)

我找到了答案 - 设置上下文的合并策略,只需执行

context.mergePolicy = NSMergePolicy(merge: NSMergePolicyType.mergeByPropertyObjectTrumpMergePolicyType)

我试图做起来惹恼了

context.mergePolicy = mergeByPropertyObjectTrumpMergePolicyType)

但我想有必要产生一个NSMergePolicy对象。我只是假设默认情况下实际的合并策略(mergeByPropertyObjectTrumpMergePolicyType)的类型是正确的。

答案 1 :(得分:0)

合并策略在coredata中用于解决持久性存储和不同托管对象上下文之间的冲突问题,这取决于您哪种合并策略适合您的应用程序。 从代码片段中可以看出您正在使用单个托管对象conext。 请尝试以下代码-

appDelegate.persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
appDelegate.persistentContainer.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyStoreTrump

答案 2 :(得分:0)

您可以在启动persistentContainer时放置mergePolicy

var persistentContainer: NSPersistentContainer = {
        let modelURL = Bundle.main.url(forResource: DB_NAME, withExtension: "momd")!
        let container = NSPersistentContainer.init(name: DB_NAME, managedObjectModel: NSManagedObjectModel(contentsOf: modelURL)!)
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
            if let error = error as NSError? {
                QiscusLogger.errorPrint("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()