我正在尝试更新 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
}
这对我来说😉是工作.