【问题标题】:Understanding how NSFetchedResultsController works了解 NSFetchedResultsController 的工作原理
【发布时间】:2011-09-05 07:44:52
【问题描述】:

首先,非常感谢您有时间帮助我!

我一直在学习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 的视图控制器。初始化我完全实现了NSFetchedResultsController。我有一个 barbutton 添加项目和一个名为 addButtonPressed 的方法,当按下时模态添加一个视图(从下往上)。以同样的方法,我有 Entity myEntity = [NSEntityDescription insertNNewObjectForEntityForName:@"Entity" inManagedObjectContext:context_]; 然后我告诉代码进入另一个视图。 但是,当动画向上移动新的导航控制器时,新单元格已经显示在动画中间。据我了解,这两种方法 - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath AND - (UITableViewCell *)tableView:(UITableView *)tableView 与上面代码 sn-p 中的前两个方法一起调用。我该如何解决?在我通过转到另一个视图添加新实体之前,我不希望在当前视图上显示任何内容。第二个另一个对象被调用到上下文中,更新方法必须被调用或其他东西

  3. 这段 sn-p 代码有什么作用?特别是 id

    的部分

    (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 (LESS THAN EQUAL SIGN) NSFetchedResultsSectionInfo (GREATER THEN EQUAL SIGN))

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

【问题讨论】:

  • 我建议将其细化为一个问题,并将其他问题作为单独的问题提出。现在要回答的太多了。

标签: iphone ios


【解决方案1】:

我赞同布拉德的评论,但我会给你一些建议:

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

  2. 1234563 . NSFetchedResultsController 是一个对象,它监视从 CoreData 获取的数据以进行任何更改,然后使您能够在更改发生时进行处理。要解决您的显示问题,只需将 insertNewObjectForEntityName 调用移动到您的下一个 viewController 中,当您关闭该 viewController 时,您会神奇地得到一个新行。
  3. NSFetchedResultsController 的 didChangeSection: 委托方法会在数据集中添加或删除部分时通知您。请参阅我对 #4 的回答,这应该很清楚。

  4. NSFetechedResultsController 允许您使用 sectionNameKeyPath: init 调用的一部分“分段”它获取的数据。通过提供实体中数据点的名称,您可以将数据分组到多个部分。所以回到#3 & #2,如果你碰巧在你在初始化 NSFetchedResultsController 时指定的“section”键路径中插入了一个具有新值的新实体,你会得到 didChangeSection: 调用的委托。

我建议阅读 Apple 有关 NSFetchedResultsControllerCoreData 的文档,可能还有他们的 TableView Programming Guide。不要忘记下载和使用示例代码,它在大多数情况下比文档中的理论更容易理解。

【讨论】:

    猜你喜欢
    • 2016-02-20
    • 2012-12-11
    • 2011-02-18
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多