Swift 即使设置了合并策略,保存时也会发生NSConstraintConflicts冲突

Swift 即使设置了合并策略,保存时也会发生NSConstraintConflicts冲突,swift,core-data,nsmergepolicy,Swift,Core Data,Nsmergepolicy,我有一个核心数据堆栈,它只显式使用主上下文,并且只在context.performAndWait块中更改/创建持久对象。如果我需要背景上下文,我总是使用以下代码块: persistentContainer.performBackgroundTask() {context in context.performAndWait { defer { context.save() persistentConta

我有一个核心数据堆栈,它只显式使用主上下文,并且只在context.performAndWait块中更改/创建持久对象。如果我需要背景上下文,我总是使用以下代码块:

persistentContainer.performBackgroundTask()
{context in
    context.performAndWait
    {
        defer
        {
            context.save()
            persistentContainer.context.save()
        }
        //make changes here
    }
} 
主上下文的合并策略在创建persistentStore时设置为NSOverwriteMergePolicy,当我保存后台上下文时,我希望用在后台上下文中创建的任何“新”对象覆盖主上下文中的任何“旧”对象。相反,我得到的是一个NSConstraintConflict错误,因为后台上下文使用默认合并策略(不确定为什么,我希望它继承主上下文的合并策略。)当我显式设置后台上下文的合并策略时,根据我设置的约束,我最终得到了不应该有重复的对象的副本。在这种情况下,clientID属性对于任何给定的客户端实体都必须是唯一的

我觉得我没有正确地合并上下文。我现在所做的只是保存背景上下文,然后保存主上下文,大致如上图所示。但是,如果没有正确合并,为什么在背景上下文中创建的对象与主上下文中的对象具有相同的属性时会发生约束错误?当我在主上下文上执行提取请求时,为什么会出现重复项


我只花了大约两个月的时间使用核心数据,我所知道的一切都来自文档或这里,所以我肯定有些东西我只是不知道。有没有关于我做错了什么的想法?

结果是我没有为我看到的重复实体设置约束。设置约束可以消除重复的对象

为了解决每次在后台上下文中保存时NSConstraintConflict错误的问题,我使用以下自定义类使使用我使用的函数创建的所有后台上下文具有相同的合并策略:

class MergePolicedNSPersistentContainer: NSPersistentContainer
{
    override func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void)
    {
        super.performBackgroundTask()
        { context in
            context.mergePolicy = PersistenceManager.shared.mergePolicy
            //PersistenceManager is a custom singleton class where I do lots of custom coreData stuff, mostly sanity checks and locks. In this case I use it to store a merge policy instance to use here.
            block(context)
        }
    }
}
在自定义PersistenceManager类中初始化我的数据存储时:

lazy var persistentContainer: MergePolicedNSPersistentContainer = {

    let container = MergePolicedNSPersistentContainer(name: "MyAppDataModel")
    container.loadPersistentStores()
    { (storeDescription, error) in

        container.viewContext.mergePolicy = self.mergePolicy

        if let error = error as NSError?
        {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    }
    return container
}()

事实证明,我没有为看到重复的实体设置约束。设置约束可以消除重复的对象

为了解决每次在后台上下文中保存时NSConstraintConflict错误的问题,我使用以下自定义类使使用我使用的函数创建的所有后台上下文具有相同的合并策略:

class MergePolicedNSPersistentContainer: NSPersistentContainer
{
    override func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void)
    {
        super.performBackgroundTask()
        { context in
            context.mergePolicy = PersistenceManager.shared.mergePolicy
            //PersistenceManager is a custom singleton class where I do lots of custom coreData stuff, mostly sanity checks and locks. In this case I use it to store a merge policy instance to use here.
            block(context)
        }
    }
}
在自定义PersistenceManager类中初始化我的数据存储时:

lazy var persistentContainer: MergePolicedNSPersistentContainer = {

    let container = MergePolicedNSPersistentContainer(name: "MyAppDataModel")
    container.loadPersistentStores()
    { (storeDescription, error) in

        container.viewContext.mergePolicy = self.mergePolicy

        if let error = error as NSError?
        {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    }
    return container
}()

我可能已经发现了问题——我在订单实体上设置了约束,但忘记了在客户实体上设置约束。现在检查是否修复了我遇到的重复对象问题。我可能已经找到了问题-我在订单实体上设置了约束,但忘记了在客户实体上设置约束。现在检查是否修复了我遇到的复制对象问题。