需要澄清NSFetchedResultsController和NSFetchedResultsControllerDelegate

在SO中有很多关于NSFetchedResultsController和delegate的问题/回复。 有时代表会开火,有时不会。 而且由于核心数据相当复杂,因此很难理解正在发生的事情而不花费大量时间。 此外,文件说有几个问题,但没有列出。

在各种版本的iOS上,NSFetchedResultsController有几个已知问题和行为更改。

因此,我需要澄清一下这类课程的行为。 特别是,从文档中可以写出以下内容:

因此,控制器有效地具有三种操作模式,由它是否具有委托以及是否设置了缓存文件名来确定。

无跟踪:委托设置为nil。 控制器只是提供对执行提取时的数据的访问。

仅内存跟踪:委托是非零的,文件缓存名称设置为nil。 控制器监视其结果集中的对象并更新部分和订购信息以响应相关变化。

完全持久跟踪:委托和文件缓存名称是非零的。 控制器监视其结果集中的对象并更新部分和订购信息以响应相关变化。 控制器维护其计算结果的持久高速缓存。

我正在开发一个非常复杂的应用程序,我正在利用NSFetchedResultsController从商店检索数据并将其显示在表中。 显示的托管对象具有syncStatus布尔变量,以validation它们是否已与外部服务同步。 syncStatus变量不显示在单元格中,显示不同的信息(例如文本值)。 换句话说, syncStatus不会被触发为故障。

在表中,通过NSFetchedResultsController ,我显示了唯一未同步的元素(bool值设置为NO )。

 - (NSFetchedResultsController*)fetchedResultsController { if(_fetchedResultsController) return _fetchedResultsController; NSManagedObjectContext* mainContext = [self managedObjectContext]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; [fetchRequest setEntity:[NSEntityDescription entityForName:@"LocalEntity" inManagedObjectContext:mainContext]]; [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"syncStatus == %@", [NSNumber numberWithBool:NO]]]; [fetchRequest setFetchBatchSize:10]; // sort descriptor here... _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:mainContext sectionNameKeyPath:nil cacheName:nil]; _fetchedResultsController.delegate = self; return _fetchedResultsController; } 

用户可以选择她/他想要同步的元素,后台线程将所选元素发送给服务,对于那些,它还将syncStatus变量更改为YES

当操作完成后,由于我设置了NSFecthedResultsControllerDelegate并且我注册了NSManagedObjectContextDidSaveNotification我还在主线程中合并了通知的更改。我能够看到通知包含具有正确更改的对象 ),我希望表已更新(将不显示syncStatus设置为YES的对象)。

说到这里,问题如下。

基于doc,因为我使用仅内存跟踪选项,缺少的更新是否是由于isSyncStatus没有加载到内存但它仍然是一个错误?

你能建议我朝着正确的方向前进吗?

先谢谢你。

PS

NSFetchedResultsControllerDelegate方法正确实现。 仅在主线程中执行相同操作。

您是否正在实施NSFetchedResultsControllerDelegate方法来删除单元格?

 - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { [self.tableView beginUpdates]; } - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { UITableView *tableView = self.tableView; switch(type) { case NSFetchedResultsChangeDelete: [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; break; } } - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { [self.tableView endUpdates]; }