Core data 调试NSObjectInaccessibleException-ID为0x123456789的NSManagedObject已无效

Core data 调试NSObjectInaccessibleException-ID为0x123456789的NSManagedObject已无效,core-data,Core Data,我有一个我正在努力寻找的bug。我相信发生的情况是,我正在从基础数据库中删除一个对象,而另一个托管对象上下文(在另一个线程中)有一个错误,当它试图完成该错误时,会得到“NSObjectInAccessibleeException” 这种情况是,我有一个视图通过一个上下文访问数据,而在后台,另一个威胁是从存储中清除过期记录。后台线程应该只清除视图不需要的对象-显然不是这样,但我很难准确跟踪到底发生了什么。当我看到缺陷时,已经太晚了,这是一个相对罕见的缺陷,主要发生在现场 因此我的问题是:在调试Co

我有一个我正在努力寻找的bug。我相信发生的情况是,我正在从基础数据库中删除一个对象,而另一个托管对象上下文(在另一个线程中)有一个错误,当它试图完成该错误时,会得到“NSObjectInAccessibleeException”

这种情况是,我有一个视图通过一个上下文访问数据,而在后台,另一个威胁是从存储中清除过期记录。后台线程应该只清除视图不需要的对象-显然不是这样,但我很难准确跟踪到底发生了什么。当我看到缺陷时,已经太晚了,这是一个相对罕见的缺陷,主要发生在现场


因此我的问题是:在调试CoreData时,我是否缺少一些技巧?我是否可以从一个上下文跟踪另一个上下文中对象的生命周期?也就是说,当我删除我的对象时,是否有一种简单的方法可以查看其他上下文是否引用了同一对象?使用它,我可以构建一些测试代码来检查我的逻辑并找到错误。

当第二个上下文试图在已从持久存储中删除的对象中出错时,它在做什么

这听起来像是一个bug,可能有两个部分:您没有合并来自对等上下文的更改,并且您有一个逻辑bug导致您使用线程B中的对象,该对象已在线程a中删除


通常,您需要使用
-[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:

合并来自对等上下文的更改。我之前遇到此错误,原因是我正在清理(完成释放)我的上下文,然后后来尝试访问由该上下文管理的对象(以前)

在我的例子中,上下文是一个“scratch”上下文,当视图关闭时它就会消失。但是,我有一个后台作业,视图生成了这个作业,它想要更新对象

我最终为托管对象创建了一个访问器,当[managedObject isFault]为true时,该访问器返回nil。然后在我的代码中,我检查访问器选择器的值,以确保我有一个有效的对象来处理(比如说,当我的后台工作最终完成时)


我对核心数据非常陌生,因此可能有更好/更聪明的方法来实现这一点,但我认为它解决了我的问题

解决方案是清除和清除相结合。在我释放了NSManagedObjectContext后,一个地图视图保留在其委托上。Mapkit向代理询问注释的坐标,我的代理对象试图查询处于已发布上下文中的对象(类似于Jason的问题)


修复方法如Jake的博客文章所述-完成地图视图后将委托设置为零。

我也遇到了这个问题。我做了一些重构,以遵循苹果公司的“查找或创建”模式,实现数据的批量导入。我创建了一个专门用于导入的新上下文,方法是按照建议将undomanager设置为nil。 因此:

然后,我创建了一个fetchRequest来检索存储在数据库中的对象id,在导入循环中,我测试了对象的id,以确定它是否包含在检索到的id数组中。。。问题是,在给定的时间间隔内,我正在保存importContext并重置它。因为我错误地引用了importContext而不是defaultContext,所以我得到了那个错误。我只是简单地改变了一下:

NSArray *storedObjects = [importContext executeFetchRequest:checkRequest error:&fetchError];
与:


我认为这里有两个bug,我同意它们是什么:-(我需要的是一种跟踪它们的方法。是否合并来自对等上下文的更改?出于调试目的,您可以在保存上下文时记录删除的对象。如果您知道所有其他现存上下文是什么,您也可以检查用这些上下文注册的对象,但必须以线程安全的方式进行。您是的。我决定我需要修复整个线程情况来解决这个缺陷。这不是小事,但可能对我的健康有好处。吉姆,你为什么要丢弃我的iPhone标签?我在iPhone上工作,所以我没有CoreData绑定。罗杰-我把iPhone标签放回去了。但这确实是一个通用的核心数据问题,可能会发生在任何桌面上p或移动平台。所以我已经诊断出这是一个iPhone问题,尽管可能发生在任何地方。Ben,为什么要删除iPhone特定的标签并添加cocoa touch(iPhone特定的标签)?Jason,感谢您再次提醒我注意这一点。我最近修复了我的错误,这是清理和映射工具包的组合-映射视图使其委托太长。在您的情况下,您可能不应该从后台线程访问相同的NSMAnagedObject上下文-CoreData不是线程安全的。相反,您应该传递NSManagedObjectReference到您的后台任务。是的,您肯定是对的。在我的例子中,在实际编辑对象之前,我跳回了主线程(在那里我创建了所有上下文),但当它的上下文已经结束时,这仍然不好。这是什么“NSManagedObjectReference”你所说的?不存在,根据文档…他可能是指
NSManagedObjectID
s.link断开了。你有新的吗,或者你能解释一下吗?我想我有。问题是有些类对其委托持有弱引用,并在其被解除分配后向其发送消息。如果你看到这个问题,请发s请确保在您所代表的任何类中都没有委托(或数据源)引用。感谢您的澄清。这也是我在iOS 8.0上遇到的问题。在委托中,我访问了一个已删除的托管对象。对于iOS用户,请注意一点。在iOS上,
undoManager
属性默认为
nil
NSArray *storedObjects = [importContext executeFetchRequest:checkRequest error:&fetchError];
NSArray *storedObjects = [defaultContext executeFetchRequest:checkRequest error:&fetchError];