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

Posted

技术标签:

【中文标题】如何在 Swift 4 CoreData 中设置合并策略【英文标题】:How to set merge policy in Swift 4 CoreData 【发布时间】:2018-05-05 21:26:28 【问题描述】:

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

【问题讨论】:

点赞this @SevySonip 看起来不错 - 我没有特别找到这个特定的帖子,我给我的一位同事发了一封电子邮件,他给了我答案,我已经在下面发布了。 【参考方案1】:

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

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

我试图做却被绊倒了

context.mergePolicy = mergeByPropertyObjectTrumpMergePolicyType)

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

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

【参考方案4】:

在 Swift 5 中,一旦您使用 Core Data 创建了一个项目,您的项目目录中就会有 Persistence.swift 文件。 在这个类中,将 mergePolicy 代码放在 init() 函数的最后。

init(inMemory: Bool = false) 
   ....
  
   container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

这对我有用?。

【讨论】:

以上是关于如何在 Swift 4 CoreData 中设置合并策略的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中获取 CoreData 属性的“预期”类型?

如何在 Alamofire 4 和 Swift 3 中设置方法、标题、参数

如何在 swift 4 中的 UserDefalts 中设置自定义类数组数据

如何在 Core Data 中使用 swift 4 Codable?

如何在 Core Data 中使用 swift 4 Codable?

如何在 Core Data 中使用 swift 4 Codable?