NSManagedObjectContext无法删除其他上下文中的对象

时间:2011-05-02 23:57:15

标签: iphone core-data nsmanagedobject

我有两个实体,每个实体都在自己的UITableView部分显示。

我已启用编辑功能,允许用户通过向右滑动来删除行。这适用于第一个实体,但是当我尝试删除第二个实体中的对象时,我收到此错误:

An NSManagedObjectContext cannot delete objects in other contexts

我得到错误说的内容,但我看不出它在这里是如何适用的。我使用对上下文的保留引用来创建,获取和删除数据库中的所有对象,因此我确信只有一个上下文。我也没有使用多线程。知道会发生什么吗?

6 个答案:

答案 0 :(得分:24)

您从同一实例获取NSManagedObject的上下文是否与您用来删除NSManagedObject的上下文相同?如果没有,您需要:

  • 拥有对同一NSManagedObjectContext的共享引用,以便从您创建或从中获取的相同上下文中删除该对象。如果您没有使用多个线程,那么您只需要在代码中调用[[NSManagedObjectContext alloc] init]

  • 如果您必须使用NSManagedObjectContext的两个不同实例,请从第一个上下文中获取的objectID中获取NSManagedObject,以便稍后调用:

    [context deleteObject:[context objectWithID:aObjectID]];
    

    上下文之间NSManagedObjectID是相同的,但NSManagedObject本身不是。

答案 1 :(得分:0)

这个答案阐述了Riley Dutton关于错误信息具有误导性的评论中描述的案例。

NSManagedObject的子类的对象传递给deleteObject:时,将显示错误消息。 Riley只是通过明确地传入错误的对象来解决问题,但是我通过Core Data的变化来实现这一目标。

我的项目部署目标设置为7.0,即使在iOS 9.3上运行,此代码仍可正常运行:

NSArray *entries = @[self.colorList.colors, self.emotionList.emotions, self.shapeList.shapes];
    for (id entry in entries) {
        [[self managedObjectContext] deleteObject:entry];
    }

当我将项目部署目标更新为9.3时,我开始收到错误消息。

以下是entry

的说明
Relationship 'colors' fault on managed object (0x7fd063420310) <MyColorList: 0x7fd063420310> (entity: MyColorList; id: 0xd000000000640006 <x-coredata://12556DEF-F77E-4EFF-AAE6-55E71A3F5420/MyColorList/p25> ; data: {
    attachedThing = "0xd0000000000c0004 <x-coredata://12556DEF-F77E-4EFF-AAE6-55E71A3F5420/MyThing/p3>";
    colors = "<relationship fault: 0x7fd063468f30 'colors'>";
})

Apple似乎更改了Core Data何时触发故障并实际从持久性存储协调器中提取数据的规则。

这个修改解决了这个问题:

NSArray *entries = @[self.colorList.colors, self.emotionList.emotions, self.shapeList.shapes];
    for (id entry in entries) {
        for (id e in entry) {
            [[self managedObjectContext] deleteObject:e];
        }
    }

此时我不知道这是否是解决此问题的理想方法,或者是否有更规范的方法告诉Core Data触发故障并从磁盘读取数据。

答案 2 :(得分:0)

我用这个:

  func delete(object: YourManagedObject) {
    guard let context = object.managedObjectContext else { return }

    if context == self.viewContext {
      context.delete(object)
    } else {
      self.performBackgroundTask { context in
      context.delete(object)
    }
  }

  try? self.viewContext.save()
}

基本上,您要删除的对象很可能是由 NSPersistentContainer viewContext 提供的。因此,尝试从私人背景环境中删除不会起作用。

答案 3 :(得分:0)

我不确定它是否能回答您的问题,但是当我尝试在Swift中删除CoreData对象时发生了类似的崩溃。我修复了它的objectId

func deleteNumber(phoneNumber: PhoneNumber) {
    let objectToDelete = container.viewContext.object(with: phoneNumber.objectID)
    container.viewContext.delete(objectToDelete)

//save context
    if container.viewContext.hasChanges {
        do {
            try container.viewContext.save()
        } catch {
            print("An error occurred while saving: \(error)")
        }
    }
}

答案 4 :(得分:0)

在补充使用dominostars给出的答案时,使用SwiftUI时,只需像@Environment(\.managedObjectContext) var moc一样声明对托管对象上下文的引用,然后将此引用传递给其他需要访问的视图。不要两次声明引用。

答案 5 :(得分:-2)

好吧,试试这个;这可以解决您的问题: -

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
//delete Entity
});

然后得到了同样的错误。

尝试删除主线程中的实体后,此问题已修复。