【问题标题】:Core Data EXC_BAD_ACCESS when deleting删除时的核心数据 EXC_BAD_ACCESS
【发布时间】:2019-04-05 18:18:05
【问题描述】:

从 Core Data 中删除对象时获取 EXC_BAD_ACCESS。任何想法如何解决这个问题?可能需要阅读一些核心数据原则 (?)

func deleteEntity(_ entity : String) {

        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)

        print("Object count:  \(context.registeredObjects.count)") // prints 0 here
        do {
            let results = try context.fetch(fetchRequest)
            for managedObject in results {
                let managedObjectData : NSManagedObject = managedObject as! NSManagedObject
                if !managedObjectData.isDeleted{
                    context.delete(managedObjectData)  // EXC_BAD_ACCESS here, fetch request returns 1 item here!
                }
            }
            try context.save()
        } catch let error {
            print(error)
        }
    }




Crashed: com.apple.main-thread
0  CoreData                       0x1114c7293 -[NSManagedObjectContext(_NSInternalAdditions) _registerObject:withID:] + 35
1  CoreData                       0x1114c5569 -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:optionalHandler:withInlineStorage:] + 217
2  CoreData                       0x1114d0512 _PF_FulfillDeferredFault + 882
3  CoreData                       0x1114dfe9e _PF_Handler_Primitive_GetProperty + 110
4  CoreData                       0x1114dfca3 -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:] + 323
5  CoreData                       0x1114dfb39 -[NSManagedObject(_NSInternalMethods) _newAllPropertiesWithRelationshipFaultsIntact__] + 89
6  CoreData                       0x1114dfa2b -[NSManagedObjectContext(_NSInternalChangeProcessing) _establishEventSnapshotsForObject:] + 75
7  CoreData                       0x1114f7168 -[NSManagedObjectContext deleteObject:] + 136

编辑: 上下文似乎有问题。我也尝试删除整个商店,但似乎保留了一件,导致崩溃。稍后在不同的视图中添加此特定项目。也许这与人际关系有关。调试 -com.apple.CoreData.ConcurrencyDebug 1 堆栈跟踪也显示

“一个 NSManagedObject 只能在单个 NSManagedObjectContext 中(或被其观察)。”

【问题讨论】:

  • 您的代码中函数的意图似乎是删除给定实体的所有对象。这真的是你的意图吗?
  • 是的,应该删除所有对象。之前也尝试过移除持久化存储文件(包括context.reset这个函数之后。
  • 您找到解决方案了吗?尝试为 MO 的属性设置值时,我遇到了类似的崩溃和几乎相同的堆栈跟踪。我无法重现它,它只是发生在 2 个不同的用户身上。
  • @Gabriel Gava:我没有设法找出导致崩溃的真正原因,但我不再遇到这个特定问题了。在插入可能与它有关的数据后,我删除了“savePrivateContext()”调用。我也有三种不同的上下文,并了解到在使用 Core Data 时引用正确的上下文非常重要......

标签: swift core-data nsmanagedobjectcontext


【解决方案1】:

删除一个实体的所有对象的常用方法是

func deleteEntity(_ entity : String) throws {
    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: entity)
    let results = try context.fetch(fetchRequest)
    for managedObject in results {
       context.delete(managedObject) 
    }

    try context.save()
}

不过在 iOS 9+、macOS 10.11+ 中还有更好的方法

func deleteEntity(_ entity : String) throws {
    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: entity)
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: request as! NSFetchRequest<NSFetchRequestResult>)
    let persistentStoreCoordinator = context.persistentStoreCoordinator!
    try persistentStoreCoordinator.execute(deleteRequest, with: context)

    try context.save()
}

【讨论】:

  • 也试过后一种,批量删除,但在我的情况下它根本不起作用。即使self.context.registeredObjects.count 返回 0,这些商品仍会保留在商店中
  • registeredObjects 无关紧要。检查save 行是否与上下文在同一线程上运行。
【解决方案2】:

我发现你的代码有几个问题……

  • NSManagedObjectContext.registeredObjects.count 将计算上下文中所有实体的所有对象。这可能不是您想要的(除非您的数据模型中只有一个实体)。
  • 我没有看到 do{...} 的任何退出。
  • managedObjectData 似乎与 managedObject 相同,除了声明为不为零,而实际上它可能为零。 (这可能是导致崩溃的原因。)
  • 在循环退出后,您应该只调用一次context.save()

但是无论如何您都不应该使用该代码。相反,将其替换为删除给定实体的所有对象的更好方法,如this question 的回答中所述。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 2011-10-11
    • 1970-01-01
    相关资源
    最近更新 更多