我有一个仅明确使用主上下文的核心数据堆栈,并且仅在上下文中更改/创建持久对象。如果我需要背景上下文,我始终使用以下代码块:
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)
}
}
}
在自定义PersistenceNager类中初始化数据存储时:
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
}()