了解NSFetchedResultsController的工作原理

时间:2011-09-05 07:44:53

标签: iphone ios

首先,如果你有时间帮助我,非常感谢你!

我一直在学习NSFetchedResultsController,我尽可能多地了解它,然而,有些事情让我很困惑。这段代码来自我在网上找到的教程。基本上我有最简单的获取控制器设置与这样的真正花哨的方法

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [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 NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            // Reloading the section inserts a new row and ensures that titles are updated appropriately.
            [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

 (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription 
        entityForName:@"FailedBankInfo" inManagedObjectContext:_context];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] 
        initWithKey:@"details.closeDate" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetchRequest setFetchBatchSize:20];

    NSFetchedResultsController *theFetchedResultsController = 
        [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
            managedObjectContext:_context sectionNameKeyPath:nil 
            cacheName:@"Root"];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    [sort release];
    [fetchRequest release];
    [theFetchedResultsController release];

    return _fetchedResultsController;    

}
  1. 我是否需要每次为不同的视图控制器创建一个新的获取控制器?例如,如果我在一个列表视图中有一个企业列表。然后我点击其中一个并将我带到该公司的员工列表中,我必须使用不同的fetchedViewController,因为我需要重新指定实体键吗?见上文我的实现。

  2. 使用我当前的实现,它非常适合列出项目。假设我有一个名为VC的视图控制器。 init我完全实现了NSFetchedResultsController。我有一个barbutton添加项和一个名为addButtonPressed的方法,当按下模态时添加一个视图(从下往上)。在这种方法中,我有 Entity myEntity = [NSEntityDescription insertNNewObjectForEntityForName:@"Entity" inManagedObjectContext:context_];然后我告诉代码进入另一个视图。 HOWEVER ,当动画向上移动新导航控制器时,新单元格已经在动画中显示。从我的理解这两个方法 - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath AND - (UITableViewCell *)tableView:(UITableView *)tableView与上面代码段中的前两个方法一起被调用。我该怎么办呢?我想要在当前视图中显示任何内容,直到我通过转到另一个视图添加新实体。第二个另一个对象被调用到上下文中,更新方法必须被调用或者什么

  3. 这段代码的作用是什么?特别是id <1的部分。东西&gt;

    (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id NSFetchedResultsSectionInfo)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    switch(type) {
    
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
    

    } 编辑:神圣$#$,格式化令人沮丧。在上面的代码中应该有didChangeSection:(id(少于等于标志)NSFetchedResultsSectionInfo(大于等号))

  4. 4我在哪里可以了解更多相关信息。即各个内容更新方法的作用以及调用它们的时间等。另外NSFetchedResultcontroller是否作为单个数组?这意味着如果我想要一个包含多个部分的tableview,我需要更多的ViewControllers?再次感谢!

1 个答案:

答案 0 :(得分:4)

我是Brad的评论,但我会给你一些指示:

  1. 基本上是的,您需要为要查询的每个实体使用新的NSFetchedResultsController。但是,您根本不需要使用NSFetchedResultsController,这只是一个很好的类,可以让您在问题#2中使用tableView做一些奇特的事情。

  2. 您的问题是您从tableViewController调用[NSEntityDescription insertNNewObjectForEntityForName:@"Entity" inManagedObjectContext:context_];,并且一旦调用NSFetechedResultsController将收到一条消息,指出已插入行,则触发{{{{{{{{{{{{{{{{{{{{{{{{{ 1}}方法。 NSFetchedResultsController是一个对象,它监视从CoreData获取的任何更改的数据,然后让您能够在发生更改时执行操作。要解决显示问题,只需将insertNewObjectForEntityName调用移动到下一个viewController中,当您解除该viewController时,您会有一个新行。

  3. NSFetchedResultsController的didChangeSection:delegate方法通知您是否已从数据集中添加或删除了某个部分。请参阅我对#4的回答,这应该是明确的。

  4. NSFetechedResultsController允许您使用sectionNameKeyPath:init调用的一部分“分割”它所获取的数据。通过在实体中提供数据点的名称,您可以将数据分组。所以回到#3&amp; #2如果您碰巧在启动NSFetchedResultsController时指定的“section”键路径中插入了一个具有新值的新实体,那么您将获得didChangeSection:delegate被调用。

  5. 我建议您在NSFetchedResultsControllerCoreData及其TableView Programming Guide上阅读Apples文档。不要忘记下载并使用示例代码,在大多数情况下,它比文档中的理论更容易理解。