如何在 Swift 4 CoreData 中设置合并策略



我正在尝试更新 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,但我不知道如何将所述策略实际设置为合并策略。

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

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

我被绊倒了

context.mergePolicy = mergeByPropertyObjectTrumpMergePolicyType)

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

你可以在启动 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
}()

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

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

在 Swift 5 中,一旦你创建了一个包含 Core Data 的项目,那么你的项目目录中就有了 Persistence.swift 文件。 在此类中,将 mergePolicy 代码放在 init() 函数的最后一个。

init(inMemory: Bool = false) {
....

container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
}

这对我来说😉是工作.

最新更新