当前位置: 首页 > 知识库问答 >
问题:

IOS/SWIFT核心数据合并冲突

谷梁星雨
2023-03-14

为了更新核心数据中的数据(当核心数据中已经有数据时),我删除了所有数据,然后重新插入数据。但我不知道为什么会发生合并冲突。我对核心数据还不熟悉,所以我也搞不清楚它到底出了什么问题。我想我需要更改我的deleteAll函数,但我不知道该更改什么。

代码如下。

Could not merge changes.
Error Domain=NSCocoaErrorDomain Code=133020 "Could not merge changes." UserInfo={conflictList=(
    "NSMergeConflict (0x6000008fdd00) for NSManagedObject (0x600003e80e60) with objectID '0x95773100e3922989 <x-coredata://60FADEF9-22B4-46FC-B17C-2B722FE843F7/Languages/p79417>' with oldVersion = 1 and newVersion = <deleted> and old object snapshot = {\n    code = es;\n    icon = spain;\n    isChecked = 0;\n    title = Spanish;\n}",
    "NSMergeConflict (0x6000008fda00) for NSManagedObject (0x600003e80aa0) with objectID '0x95773100e2722989 <x-coredata://60FADEF9-22B4-46FC-B17C-2B722FE843F7/Languages/p79414>' with oldVersion = 1 and newVersion = <deleted> and old object snapshot = {\n    code = fr;\n    icon = france;\n    isChecked = 1;\n    title = French;\n}",
    "NSMergeConflict (0x6000008fdbc0) for NSManagedObject (0x600003e80cd0) with objectID '0x95773100e3322989 <x-coredata://60FADEF9-22B4-46FC-B17C-2B722FE843F7/Languages/p79420>' with oldVersion = 1 and newVersion = <deleted> and old object snapshot = {\n    code = cn;\n    icon = china;\n    isChecked = 0;\n    title = Chineses;\n}",
    "NSMergeConflict (0x6000008fdd80) for NSManagedObject (0x600003e80d20) with objectID '0x95773100e3d22989 <x-coredata://60FADEF9-22B4-46FC-B17C-2B722FE843F7/Languages/p79419>' with oldVersion = 1 and newVersion = <deleted> and old object snapshot = {\n    code = kr;\n    icon = \"south-korea\";\n    isChecked = 0;\n    title = Korean;\n}",
    "NSMergeConflict (0x6000008fdc80) for NSManagedObject (0x600003e80b40) with objectID '0x95773100e2122989 <x-coredata://60FADEF9-22B4-46FC-B17C-2B722FE843F7/Languages/p79413>' with oldVersion = 1 and newVersion = <deleted> and old object snapshot = {\n    code = us;\n    icon = \"united-states-of-america\";\n    isChecked = 1;\n    title = English;\n}",
    "NSMergeConflict (0x6000008fddc0) for NSManagedObject (0x600003e80dc0) with objectID '0x95773100e3f22989 <x-coredata://60FADEF9-22B4-46FC-B17C-2B722FE843F7/Languages/p79418>' with oldVersion = 1 and newVersion = <deleted> and old object snapshot = {\n    code = jp;\n    icon = japan;\n    isChecked = 0;\n    title = Japanese;\n}",
    "NSMergeConflict (0x6000008fdb80) for NSManagedObject (0x600003e809b0) with objectID '0x95773100e2522989 <x-coredata://60FADEF9-22B4-46FC-B17C-2B722FE843F7/Languages/p79415>' with oldVersion = 1 and newVersion = <deleted> and old object snapshot = {\n    code = ru;\n    icon = russia;\n    isChecked = 1;\n    title = Russian;\n}",
    "NSMergeConflict (0x6000008fda40) for NSManagedObject (0x600003e801e0) with objectID '0x95773100e3b22989 <x-coredata://60FADEF9-22B4-46FC-B17C-2B722FE843F7/Languages/p79416>' with oldVersion = 1 and newVersion = <deleted> and old object snapshot = {\n    code = it;\n    icon = italy;\n    isChecked = 1;\n    title = Italien;\n}"
), NSExceptionOmitCallstacks=true}
private var persistenceManager = PersistenceManager.shared
private let request: NSFetchRequest<Languages> = Languages.fetchRequest()
private var coreDataLanguages: [Languages]

..

persistenceManager.deleteAll(request: request)
coreDataLanguages.forEach { language in    
    let language = Setting(isChecked: language.isChecked, title: language.title!, code: language.code!, icon: language.icon!)
    persistenceManager.insertLanguage(language: language)
}
class PersistenceManager {
    
    static var shared: PersistenceManager = PersistenceManager()
    
    var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "Setting")
        
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()
    
    var context: NSManagedObjectContext {
        return self.persistentContainer.viewContext
    }

    func saveContext() {
        if context.hasChanges {
            do {
                try context.save()
                print("Data Saved to Context")
            } catch {
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }

    @discardableResult
    func insertLanguage(language: Setting) -> Bool {
        let entity = NSEntityDescription.entity(forEntityName: "Languages", in: self.context)
        if let entity = entity {
            let managedObject = NSManagedObject(entity: entity, insertInto: self.context)
            managedObject.setValue(language.isChecked, forKey: "isChecked")
            managedObject.setValue(language.title, forKey: "title")
            managedObject.setValue(language.code, forKey: "code")
            managedObject.setValue(language.icon, forKey: "icon")
            
            do {
                try self.context.save()
                return true
            } catch {
                print(error)
                print(error.localizedDescription)
                return false
            }
        } else {
            return false
        }
    }

    @discardableResult
    func deleteAll<T: NSManagedObject>(request: NSFetchRequest<T>) -> Bool {
        let request: NSFetchRequest<NSFetchRequestResult> = T.fetchRequest()
        let delete = NSBatchDeleteRequest(fetchRequest: request)
        
        do {
            try self.context.execute(delete)
            try self.context.save()
            return true
        } catch {
            print(error.localizedDescription)
            return false
        }
    }
}

我可以使用saveContext来保存核心数据,但我也需要更改位置,并且在重新启动后它不起作用。重新启动后,元素的顺序就像我第一次设置的一样。所以我想知道为什么如果我删除所有的数据,它是不起作用的。

如果您能提供任何帮助,我将不胜感激。

共有1个答案

汝弘深
2023-03-14

批处理删除请求直接转到持久存储区,绕过托管对象上下文。不清楚您何时看到该错误(在删除时保存,还是在插入时保存?)但这可能是因为上下文认为某个对象存在,然后您将其从存储中删除,而不让上下文知道。

因为您只处理少量对象,所以最好不要执行批处理插入(因为您无论如何都需要用结果更新上下文,为什么不单独删除它们然后保存)。

更好的方法是执行upsert(update/insert),它将保持每个语言对象不变,只更新属性。这将维护对象之间的任何关系,并防止在代码的其他部分持有对语言对象的引用时出现不可访问的错误。

您可以在以下网址阅读关于核心数据中的upserts:https://www.upbeat.it/upsert-in-core-data/

 类似资料:
  • 问题内容: 对于如何迅速删除所有核心数据,我有些困惑。我创建了一个带有链接的按钮。单击按钮后,我将看到以下内容: 然后,我想出了各种方法来尝试删除所有核心数据内容,但似乎无法正常工作。我已经使用removeAll从存储的数组中删除,但是仍然不能从核心数据中删除。我假设我需要某种类型的for循环,但是不确定如何从请求中进行。 我尝试应用删除单行的基本原理 但是,这样做的问题是,当我单击按钮时,我没有

  • 问题内容: 不幸的是,新的Core Data语义使我发疯。我之前的问题有一个干净的代码,因为头文件的自动生成不正确,因此无法正常工作。现在,我继续删除对象的工作。我的代码似乎很简单: 我用代替进行了“硬”调试,它向我展示了正确的对象。所以我只需要删除它。 PS没有。现在NSManagedContext只有 问题答案: 在您的情况下,提取的结果是托管对象 的 数组,因此您可以枚举该数组并删除所有匹配

  • 问题内容: Xcode 8更新: 在Xcode 8中,需要转到Core Data Model Editor并显示File Inspector。底部附近是代码生成的选项。选择快速。 编辑 :我找到了从核心数据实体生成Swift模型的解决方案: 在Xcode上: 编辑器 >创建NSManagedOjbect>单击按钮“下一步”>单击按钮“下一步”>选择“快速”语言>单击按钮“创建” 我使用Core D

  • 问题内容: 我读过一些博客,但是我仍然对如何使用NSPersistentContainer 创建实体并保存它感到困惑。通过在块中调用便捷方法创建实例后,如果检查是否返回false并说没有要保存的内容,如果我调用save (为此块创建的后台MOC),则会收到如下错误: Code=133020 “Could not merge changes.” UserInfo={conflictList=( “N

  • 我正在开发一个以时事通讯风格界面为中心的iPad应用程序。我使用苹果的UIPageViewController来做到这一点。 我遇到了很多我不完全理解的错误,我希望有人能帮助我找到解决方法。 在这个界面上翻页时,应用程序偶尔会冻结(这就是为什么它如此令人沮丧,因为它不容易复制)。我在调试器中暂停应用程序,这是它显示给我的http://cl.ly/image/1y3c2x351t0T. 我很清楚这是

  • 问题内容: 我知道核心数据不是数据库,并且有很多差异。是这个吗? 在数据库中,我通常有以下内容 A->> B->> C “ A”有很多“ B”,其中有很多“ C” 查询“给我所有具有c.attr =’X’的A可以很容易地写成: 在Core Data中,我想做同样的事情,但是要使用类似这样的谓词: 这样做会导致错误:“ NSInvalidArgumentException”,原因:“此处不允许使用多