解决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在不同的上下文,我试图保存…
嗯,在代码中我会改变一些东西。
-
使用错误指针,这是他们的目的。 你可能会从中得到一个解决scheme。
NSError
一个NSError
指针,检查-save:
call的返回值,然后吐出错误,以便在出现故障时进行控制。 -
你的队列pipe理有点可怕。 而不是做
dispatch_async()
,改为-[NSManagedObjectContext performBlock:]
。 这将保证您在正在访问的上下文的正确线程/队列中。 用你写的方式是没有保证的,因此可维护性低。
一旦你做了这两个改变,你仍然失败,更新你的问题与NSError
对象的输出,我们可以看到发生了什么事情。
更新1
即使错误没有发生在保存上,你仍然想检查返回值和错误,因为它可以给我们丢失的信息。
如果/当您重现崩溃,请在这里回复。
更新2
好吧,这往往表明你正在不同的MOCs中创build对象,然后通过已经收集的关系来连接它们。 你可以发表或描述如何以及何时创build对象? 你正在使用什么MOC?
你也可以发布你的更新代码保存?
我在我的代码中也遇到了这个问题。 后来我注意到我在后台线程中使用了由主线程NSManagedObjectContext创build的托pipe对象。 由于pipe理对象是臭名昭着的线程不安全,所以我改变了我的代码,然后这个错误再也没有出现,代码工作得很好。 所以我想这是IOS的方式抱怨使用pipe理对象线程以外的线程,它已被创build或获取。
希望这个帮助。
面对相同的问题,但通过在Fetchrequest
设置此问题解决
[fetchrequest setReturnsObjectsAsFaults:NO];