2011-09-29 62 views
0

我有三个类,A,B和C. A是主类。iPhone核心数据 - 不能履行故障错误

当用户想要查看所购买的所有对象的列表时,将从A中调用B类,并显示核心数据实体中的对象列表。

在B类内部,用户可以购买新对象(应用内购买)。当用户想要购买另一个对象时,就会调用C类。

当C类被调用时,则使用

anObject = [NSEntityDescription insertNewObjectForEntityForName:@"Objects" inManagedObjectContext:context]; 

那么这个对象被分配给有关类别C的本地参考,使用类似

self.object = anObject; 
核心数据实体创建一新的对象

这个对象变量是这样声明的:

.h 
MyObjects *object; 
@property (nonatomic, retain) MyObjects *object; 

and @synthesized on .m 

MyObjects是一个核心数据c lass代表实体。

从理论上讲,对象将保留任何分配给它的对象,所以行self.object = anObject我之前输入的将保留self.object上的对象引用,对吗?

问题是,当我尝试在购买新对象后访问同一类中的self.object时,收到错误“CoreData无法完成XXX的错误”,其中XXX正好是self.object。

代码中没有任何对象从数据库中删除。对于我能识别的数据库唯一的操作是在崩溃之前的另一个课程完成的保存操作。保存是通过类似

if (![self.managedObjectContext save:&error]) ... 

是否有任何关系?可能是什么原因造成的?

回答

3

CoreData管理被管理对象的生命周期,你不应该保留和释放它们。如果您想保留对该对象的引用以便稍后可以检索该对象,则必须存储对象的ID(使用 - [NSManagedObject objectID]获取)。然后使用它来稍后使用 - [NSManagedObjectContext objectWithID:]来检索对象。

确保您了解CoreData错误。阅读documentation

+0

好。现在我正在做你说的话。我在创建对象时保存objectID引用,然后使用objectWithID检索它,并且它仍然在同一行中崩溃,也就是说,在检索对象后我正好尝试设置其属性。 – SpaceDog

+1

我们将需要查看当您存储id时的代码,然后再检索该对象。 –

+0

问题是这样的:如果我打印控制台使用objectWithID检索它后得到的对象是这样的:** (entity:Objects; id:0x1b6ca0 ; data:)**,我认为是一个错误。现在的问题是我如何“无故”...... – SpaceDog

2

前几天我有一个类似的问题(使用NSFetchedResultsController),我将fetchedObjects放入数组并收集属性以从数组对象填充表。看起来,如果数组中的对象发生故障,除非您正在对直接对象进行操作,否则您不能将其设为非故障。在我的情况下,我通过采用有问题的代码行并调用[[_fetchedResultsController objectAtIndexPath:indexPath] someAttribute]来解决问题。我会假设做类似的事情也会解决你的问题。看起来有点乏味,需要从managedObjectContext获取一个错误的值,但这是我亲自过过这个问题的唯一方法。

+0

谢谢。你能翻译一下吗? “阵列中的物体有故障”是什么意思?为什么会发生这种情况?你的意思是我的self.object可以指向一个无效的对象,即使被保留,也没有操作来删除它吗?我无法理解这一点。谢谢。 – SpaceDog

+1

对不起,我感到困惑。为了节省内存,不用时核心数据属性和关系经常出现故障。简而言之,属性被压缩。你得到的错误并不是说你的核心数据对象已经不存在了(它仍然存在于你的数据库中),只是它无法读取关于它的特定信息,因为它不能错误的属性,核心数据必须做的事情。 [这个错误指南](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html)给出了一个很好的例子,它是什么意思,当数据出现故障 – justin

+0

所以,我如何再次访问对象?我已经按照Robin的建议完成了,也就是说,我存储了对象的objectID,然后当我想要检索该对象时,我使用objectWithID获取它,但是我得到的对象再次出现故障。 – SpaceDog

1

核心数据负责管理内存中被管理对象的生命周期。了解管理对象上下文非常重要 - 阅读documentation

Apple还提供了一个完整的故障排除部分here,它除其他外包含导致错误的原因。但是,只有了解核心数据的工作原理,它才有用。

0

最有可能的错误是您保存的对象不属于托管对象上下文。如果你在不同的线程上使用同一个对象,并且这些不同的线程使用不同的托管对象上下文,那么这将会发生。