我面临一个奇怪的问题,即NSFRC fetchedObjects数组未返回其应有的所有对象。为了给您一些背景,我的应用程序有几个 ListView Controller ,每个都有一个NSFRC。我正在更新委托(delegate)方法controllerDidChangeContent中的 ListView 。我面临的问题如下:将对象存储在后台MOC中并保存后,会调用controllerDidChangeContent,但我刚刚保存在后台线程中的对象不会出现在NSFRC中。这是我用来检查的一段代码:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
NSManagedObjectContext *context = controller.managedObjectContext;
NSError *error = nil;
NSArray *array = [context executeFetchRequest:controller.fetchRequest error:&error];
if (nil != array) {
NSUInteger count = MIN(controller.fetchedObjects.count, array.count);
for (NSUInteger index=0; index<count; index++) {
NSManagedObject *a = array[index];
NSManagedObject *b = controller.fetchedObjects[index];
// Here you will see that sometimes the objects don't match
NSLog(@"%d: %@ <--> %@", index, [[a body] text], [[b body] text]);
}
}
}
我期望NSFRC fetchedObjects数组与手动executeFetchRequest返回的数组相同(我正在使用NSFRC fetchRequest手动获取数据)。然而,这种情况并非如此。与NSFRC fetchedObjects相比,手动executeFetchRequest返回的对象更多。有人知道发生了什么吗?我已经关闭了NSFRC上的缓存,但是报告了相同的行为。
谢谢!
===更新====
有关此问题的一些更新。我认为Core Data中存在一个错误,因为我能够从NSFRC中看到一些不一致的结果,而且能够通过涉及“触摸”相关对象的解决方法来解决该问题。这是一个说明正在发生的情况的场景:
想象一下以下核心数据模型:
-有Cat对象和Master对象。
-猫可以拥有一个或多个主人。
-一位主人可以拥有一只或多只猫。
-创建第一个NSFRC(我们称其为NSFRC_A),以提取所有主机名为“Master_A”的猫。谓词为{ANY master.name ==“Master_A”}。
-创建第二个NSFRC(我们称其为NSFRC_B),以提取所有主机名为“Master_B”的猫。谓词为{ANY master.name ==“Master_B”}。
-有一个主要的托管对象上下文,仅在UI线程中使用
-使用与主托管对象上下文相同的持久性存储,为每个后台线程创建了一个后台托管对象上下文。
在后台创建了一个名为“Cat_A”的猫,并将其分配给母版“Master_A”。保存背景上下文后,将适当更新主上下文。此时,NSFRC_A通知其委托(delegate)者发生了更改,并正确报告“Cat_A”。
稍后,在后台线程中,同一猫“Cat_A”被分配为主站“Master_B”。保存背景上下文后,将适当更新主上下文。此时,NSFRC_A将该更改通知其委托(delegate),并正确报告“Cat_A”。 NSFRC_B也会将该更改通知其委托(delegate)人,但不报告“Cat_A”(它的fetchedObjects中缺少它)。但是,如果我使用与NSFRC_B相同的fetchRequest手动执行获取,则可以看到返回了“Cat_A”。奇怪的是,正在返回的“Cat_A”实例被标记为错误,这说明了为什么NSFRC_B不返回“Cat_A”,因为它在内存中看不到它。
这是一个错误,因为我可以通过在将来自后台线程的更改合并到主上下文中时简单地将“Cat_A”关系记录到master来解决该问题:记录基本上会触碰对象并将其强制实现到内存中。
最佳答案
该问题似乎是NSFRC的局限性。根据苹果论坛(https://devforums.apple.com/message/765374)上的该帖子:“限制是,实体A的获取结果 Controller 不会总是捕获到实体B的更新,这将导致实体B的更新。谓词改变。”。为了解决该问题,我必须在将要查找的对象合并到主线程之前对其进行脏污处理:然后,NSFRC会检测到该更改。