我有UIManagedDocument
一些数据,我使用NSFetchedResultsController
. 数据会在后台定期更新,并将更改放入UIManagedDocument.managedObjectContext
(使用 performBlock :)。
当我从文档的主要上下文中显示数据时,一切都按预期工作。但是,一旦我在作为主上下文 ( child.parentContext = document.managedObjectContext
) 的子上下文的上下文中显示列表,我就看不到任何对象,并且控制台上会打印以下错误:
foo[17895:15203] CoreData: error: (NSFetchedResultsController)
The fetched object at index 5 has an out of order section name 'E.
Objects must be sorted by section name'
这仅在将新对象插入文档联系人后才会发生。当我等待足够长的时间自动保存时,列表显示正常。另外问题是只有当我有一个sectionNameKeyPath
集合NSFetchedResultsController
并且只有子上下文时。
这就是我设置获取结果控制器的方式,没什么特别的,所以我看不出我在这里做错了什么:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Contact"];
fetchRequest.sortDescriptors = [Contact userDefinedSortDescriptors];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"hidden == nil || hidden == NO"];
NSFetchedResultsController *fetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:_managedObjectContext
sectionNameKeyPath:[Contact userDefinedSectionNameKeyPath]
cacheName:@"ContactList"];
[Contact userDefinedSortDescriptors]
并[Contact userDefinedSectionNameKeyPath]
在运行时解决。排序描述符包含 sectionNameKeyPath 作为第一个条目。既不是也不是nil
其他有趣的东西。
编辑:澄清了一些模糊的部分。具体来说,我不会在文档托管对象上下文中调用 -save:。
编辑 2:我将尝试解释 MOC 之间的关系。
有三个托管对象上下文在起作用:
1)UIManagedDocument.managedObjectContext
通过加载文档创建。
2)有一个后台线程正在运行,它会不时更新对象。这是一个以文档 MOC 作为父级的私有队列 moc:
context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.parentContext = repository.managedObjectContext;
[context performBlock:^{ /* updates */ }];
[context performBlock:^{ [context save:NULL]; }];
3) 当用户想要进行更改时,将创建一个新的 MOC 作为文档 MOC 的子项。这是一个主队列 MOC。这是用于执行上面显示的提取的上下文。
后台更新是从 NSOperationQueue 完成的,但是对后台 MOC 的所有访问都正确地用-performBlock:
. 所有其他访问都是从主线程完成的。
编辑3:在玩一些设置时,NSFetchRequest
我发现设置时问题消失了fetchRequest.includesPendingChanges = NO
。但这不是一个可行的解决方案,因为现在用户看不到任何更新,直到 UIManagedDocument 将更改保存在后台。