删除Core Data对象时出错:NSManagedObjectContext无法删除其他上下文中的对象

时间:2011-06-13 02:18:54

标签: objective-c ios core-data

尝试从Core Data存储中删除对象时遇到问题。我在致电deleteOject时收到的错误如下:An NSManagedObjectContext cannot delete objects in other contexts.

我在网上找到了一些关于此错误的文档,但它主要涉及在多个线程中访问ManagedObjectContext,这可能会导致问题,但我目前没有处理任何其他线程。我已经完成了我的代码,试图确保我没有创建任何其他上下文,除了我在AppDelegate中创建的那个,并且找不到可能的罪魁祸首。

我正在测试的代码如下:

NSMutableSet *remoteNids = [NSMutableSet setWithObjects:@"140", @"141", nil];
for (GCEvent *event in nodeEventsFromStore) {
    if (![remoteNids containsObject:event]) {
        NSLog(@"Event no longer exists on remote. Removing object %@ from store.", event);
        [[delegate managedObjectContext] deleteObject:event];
    }
    else {
        NSLog(@"Event %@ exists on remote", event);
    }
}

2 个答案:

答案 0 :(得分:5)

核心数据极不可能骗你。我建议在你的代码中添加一个断言:

NSAssert([delegate managedObjectContext] == [event managedObjectContext], @"Found two contexts: %@ and %@", [delegate managedObjectContext, [event managedObjectContext]);

通过Xcode运行您的应用程序,并打开断点(当您点击断言时它会中断)并设置MallocStackLoggingNoCompact = YES。

当触发断言时,您可以像这样使用gdb控制台:

(gdb) info malloc [address of event's MOC]
(gdb) info malloc [address of delegate MOC]

这将打印alloc堆栈跟踪并显示您创建两个moc的位置。

答案 1 :(得分:1)

解决此问题的最简单方法是在删除之前记录托管对象上下文,然后记录每个managedObjectContext对象的GCEvent属性。如果错误正确,则两个上下文的地址将不匹配。如果您没有多个上下文,则每个managedObjectContext的{​​{1}}属性很可能是GCEvent

如果您直接初始化托管对象(即使用alloc-init),但是从未通过将其nil属性设置为上下文而将其分配给上下文,则可能会出现此错误。托管对象上下文会将除自身之外的任何值视为另一个上下文,即使这是一个零值。