我面临一个奇怪的问题,即 NSFRC fetchedObjects 数组返回的不是它应该返回的所有对象。为了给你一些背景信息,我的应用程序有几个列表视图控制器,每个控制器都有一个 NSFRC。我正在更新委托方法 controllerDidChangeContent 中的列表视图。我面临的问题如下:在后台 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 手动获取数据)。然而,这种情况并非如此。手动 executeFetchRequest 返回比 NSFRC fetchedObjects 更多的对象。有谁知道发生了什么?我已经关闭了 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 通知其委托发生了变化并正确报告“Cat_A”。
稍后,在后台线程中,同一只猫“Cat_A”被分配了主人“Master_B”。后台上下文保存后,主上下文相应更新。此时,NSFRC_A 通知其代表该更改并正确报告“Cat_A”。NSFRC_B 还通知其代表该更改,但不报告“Cat_A”(它从其 fetchedObjects 中丢失)。但是,如果我使用与 NSFRC_B 相同的 fetchRequest 手动执行提取,我可以看到“Cat_A”被返回。奇怪的是,返回的“Cat_A”实例被标记为错误,这解释了为什么 NSFRC_B 没有返回“Cat_A”,因为它在内存中看不到它。
这是一个错误,因为当来自后台线程的更改合并到主上下文中时,我可以通过简单地将“Cat_A”关系记录到 master 来修复该行为:日志记录基本上触及对象并强制将其实现到内存中。