1

在 SO 中有很多关于NSFetchedResultsController和委托的问题/回复。有时代表会开火,有时不会。而且由于 Core Data 是相当复杂的论点,如果不花大量时间在上面,很难理解发生了什么。此外,文件说有几个问题,但没有列出。

在各种 iOS 版本中,NSFetchedResultsController 存在几个已知问题和行为变化。

因此,我需要对此类的行为进行一些说明。特别是,从文档中可以看出以下内容:

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

无跟踪:委托设置为零。控制器只是提供对数据的访问,就像执行获取时一样。

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

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

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

在表中,通过NSFetchedResultsController,我显示了唯一未同步的元素(布尔值设置为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不会显示)。

说了这么多,问题如下。

基于文档,由于我使用仅内存跟踪选项,因此缺少更新是否是由于isSyncStatus未在内存中加载但仍然是错误的事实?

你能建议我正确的方向吗?

先感谢您。

附言

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

4

1 回答 1

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];    
}
于 2012-11-23T18:40:29.633 回答