解决CoreData错误:NULL _cd_rawData但对象没有变成故障

有时在使用Core-Data对象时,应用程序崩溃,出现以下错误:

CoreData:error:NULL _cd_rawData但对象没有变成故障

从我可以研究和从互联网上读取的是,当两个线程之间传递一个托pipe对象上下文并且MOC不是线程安全的时候会发生这种情况。

每当我想从CD对象访问一个属性,就会出现这个崩溃。

如果我有Person对象并且想要访问Perosn.name,那么应用程序可能会因为这个错误而崩溃(就像之前所说的那样,只要我能够随机地看到,我就不能重现它,有时候它会连续发生10次,然后不会发生一两天)。

当看这个问题时,似乎这发生在Person获取并更新Person的朋友关系(这是在后台线程上完成的,保存并合并到主线程MOC中)。

我想获得更多关于这里发生的事情的信息,为什么这个错误发生,因为它似乎很随机,如果有任何方法来防止崩溃。

以下是保存上下文的代码:

__block MyAppDelegate *blockSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [blockSelf.managedObjectContext performBlock:^{ [blockSelf.managedObjectContext save:nil]; dispatch_async(blockSelf.core_data_queue, ^{ [blockSelf.writerContext performBlock:^{ [blockSelf.writerContext save:nil]; }]; }); }]; }); 

更新1有时,当执行saveContext,我会得到以下错误:

“错误域= NSCocoaErrorDomain代码= 1550”操作无法完成。 (cocoa错误1550.)

悬挂对无效对象的引用。= null

NSLocalizedDescription =操作无法完成。 (cocoa错误1550.),NSValidationErrorValue =pipe理对象上的“朋友”关系(0x201cd340)

UID:<4C1B48C8-6309-4E8E-A590-DED497907A3A>。 资产ID:(null)。 与对象{(\ n'(null)'UID:<(null)>。)}}“

我从另一个SO问题中find了这个答案:“这是由于在不同的上下文中创build了对象,请注意不是在不同的线程上,而是在同一个线程上的不同上下文。

这似乎是这种情况,如果是我怎么能find对象的创build在不同的上下文,我试图保存…

嗯,在代码中我会改变一些东西。

  1. 使用错误指针,这是他们的目的。 你可能会从中得到一个解决scheme。 NSError一个NSError指针,检查-save: call的返回值,然后吐出错误,以便在出现故障时进行控制。

  2. 你的队列pipe理有点可怕。 而不是做dispatch_async() ,改为-[NSManagedObjectContext performBlock:] 。 这将保证您在正在访问的上下文的正确线程/队列中。 用你写的方式是没有保证的,因此可维护性低。

一旦你做了这两个改变,你仍然失败,更新你的问题与NSError对象的输出,我们可以看到发生了什么事情。

更新1

即使错误没有发生在保存上,你仍然想检查返回值和错误,因为它可以给我们丢失的信息。

如果/当您重现崩溃,请在这里回复。

更新2

好吧,这往往表明你正在不同的MOCs中创build对象,然后通过已经收集的关系来连接它们。 你可以发表或描述如何以及何时创build对象? 你正在使用什么MOC?

你也可以发布你的更新代码保存?

我在我的代码中也遇到了这个问题。 后来我注意到我在后台线程中使用了由主线程NSManagedObjectContext创build的托pipe对象。 由于pipe理对象是臭名昭着的线程不安全,所以我改变了我的代码,然后这个错误再也没有出现,代码工作得很好。 所以我想这是IOS的方式抱怨使用pipe理对象线程以外的线程,它已被创build或获取。

希望这个帮助。

面对相同的问题,但通过在Fetchrequest设置此问题解决

 [fetchrequest setReturnsObjectsAsFaults:NO];