在SO中,有很多关于NSFetchedResultsController
和委托的问题/回复。有时代表会开火,有时不会。而且由于核心数据非常复杂,因此很难在不花费大量时间的情况下理解正在发生的事情。此外,文件说有几个问题,但没有列出。
有几个已知问题和行为更改 在各种版本的iOS上使用NSFetchedResultsController。
因此,我需要澄清一下这类课程的行为。特别是,从文档中可以写出以下内容:
因此,控制器有效地具有三种操作模式 是否有委托以及是否设置了缓存文件名。
无跟踪:委托设置为nil。控制器简单 提供对执行提取时的数据访问。
仅内存跟踪:委托是非零和文件缓存名称 设置为零。控制器监视其结果集中的对象 更新部分和订购信息以响应相关 变化。
完全持久跟踪:委托和文件缓存名称 非空。控制器监视其结果集和更新中的对象 部分和订购信息以响应相关变化。该 controller维护其结果的持久缓存 计算
我正在开发一个非常复杂的应用程序,我正在利用NSFetchedResultsController
从商店检索数据并将其显示在表格中。
显示的托管对象具有syncStatus
布尔变量,以验证它们是否已与外部服务同步。 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
未加载到内存但仍然是错误的事实?< / p>
你能建议我朝着正确的方向前进吗?
提前谢谢。
P.S。
NSFetchedResultsControllerDelegate
方法正确实现。仅在主线程中执行相同操作。
答案 0 :(得分:0)
您是否正在实施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];
}