Ios NSFetchedResultsController无法在子上下文中获取
我有一个带有一些数据的Ios NSFetchedResultsController无法在子上下文中获取,ios,core-data,nsfetchedresultscontroller,uimanageddocument,Ios,Core Data,Nsfetchedresultscontroller,Uimanageddocument,我有一个带有一些数据的UIManagedDocument,我使用NSFetchedResultsController将这些数据显示在列表中。数据会定期在后台更新,并将更改放到UIManagedDocument.managedObjectContext(使用performBlock:)中 当我显示文档主上下文中的数据时,所有操作都按预期进行。但只要我在主上下文的子上下文(child.parentContext=document.managedObjectContext)中显示列表,我就看不到任何对
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'
只有在将新对象插入到“文档”联系人后,才会发生这种情况。当我等待自动保存足够长的时间时,列表显示良好。另外,只有在NSFetchedResultsController
上设置了sectionNameKeyPath
并且仅在子上下文中才存在问题
这是我设置“获取结果”控制器的方式,没有什么特别之处,因此我不知道我在这里会做错什么:
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"];
[联系userDefinedSortDescriptors]
和[联系userDefinedSectionNameKeyPath]
在运行时解析。排序描述符包含sectionNameKeyPath作为第一个条目。两者都不能是nil
或其他有趣的东西
编辑:澄清了一些模糊的部分。具体来说,我不会在文档管理对象上下文上调用-save:
编辑2:我将尝试解释主运行中心之间的关系
有三种托管对象上下文在起作用:
1) 通过加载文档创建的UIManagedDocument.managedObjectContext
2) 有一个后台线程正在运行,它会不时更新对象。这是一个专用队列主运行中心,文档主运行中心作为父级:
context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.parentContext = repository.managedObjectContext;
[context performBlock:^{ /* updates */ }];
[context performBlock:^{ [context save:NULL]; }];
3) 当用户想要进行更改时,将创建一个新的MOC作为文档MOC的子级。这是一个主队列主运行中心。这是用于执行上述提取的上下文
后台更新通过NSOperationQueue完成,但对后台MOC的所有访问都被-performBlock:
正确包围。所有其他访问都是从主线程完成的
编辑3:在处理
NSFetchRequest
上的一些设置时,我发现在设置fetchRequest.includesPendingChanges=NO
时问题消失了。但这不是一个可行的解决方案,因为现在用户在UIManagedDocument将更改保存到后台之前不会再看到任何更新。首先,这个
数据在后台定期更新,更改保存到UIManagedDocument.managedObjectContext(使用performBlock:)中
UIManagedDocuments实现自动保存,我们应该直接调用保存方法的唯一时间是在初始创建时。所有其他“保存”应通过自动保存界面完成。基本上,那就是打电话
[document updateChangeCount:UIDocumentChangeDone];
如果使用撤消管理器,这将自动完成。因此,如果要直接输入document.managedContext,只需调用上述方法通知托管文档更改已完成,其他所有操作都应自动处理
第二,我不知道你说的是什么意思:
但一旦我在子上下文中显示列表
儿童语境是什么?为什么任意上下文会看到任何东西?它是UIManagedDocument主上下文的子上下文,还是父上下文,还是其他内容
文档很清晰(对于clear的某些定义),但不幸的是,它需要阅读UIDocument、UIManagedDocument以及所有NSManagedObjectContext内容的完整文档集
当我终于对正在发生的事情了如指掌时(讽刺的是,通过阅读iCloud的工作原理),我所有与UIManagedDocument相关的问题似乎都消失了
基本上,遵循以下简单规则: