0

在我的应用程序中,我使用 Core Data 以及 NSFetchedResultsController。我需要使用 1 个表视图行来显示 9 条记录而不是 1 条记录。所以我自定义numberOfRowsInSection

方法:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    return [self numberOfRowsForNumber: [sectionInfo numberOfObjects]];
}

- (NSInteger)numberOfRowsForNumber:(NSInteger)num
{
    NSInteger a = num / 9;
    NSInteger b = num % 9;
    return a + (b == 0 ? 0 : 1);
}

添加第一条记录就可以了。但是当我添加第二条记录时,出现错误:

-[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2903.23/UITableView.m:1330 2013-11-13 06:54:56.217 TestNSFetchedResultsController[2693:a0b] CoreData 中的断言失败:错误:严重的应用程序错误。在调用 -controllerDidChangeContent: 期间,从 NSFetchedResultsController 的委托中捕获了一个异常。无效更新:第 0 节中的行数无效。更新后现有节中包含的行数 (1) 必须等于更新前该节中包含的行数 (1),加上或减去数字从该部分插入或删除的行数(1 插入,0 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。与用户信息(空)

这是否意味着 NSFetchedResultsController 仅支持 1 条记录到 1 行的映射?还是有更好的方法来完成它?

4

2 回答 2

0

如果您可以使用替代方法,那么使用TLIndexPathToolsTLIndexPathController中的类很容易做到这一点。它将所有五个委托方法整合到一个方法中,因此通常更易于使用。但更符合您的需求,它提供了一个委托方法,可让您将获取的托管对象映射到任意数据模型。这是一个将对象映射为九个组的示例:NSFetchedResultsControllerNSFetchedResultsControllerdidUpdateDataModelwillUpdateDataModel

- (TLIndexPathDataModel *)controller:(TLIndexPathController *)controller willUpdateDataModel:(TLIndexPathDataModel *)oldDataModel withDataModel:(TLIndexPathDataModel *)updatedDataModel
{
    NSArray *ungroupedItems = updatedDataModel.items;
    NSMutableArray *groupedItems = [NSMutableArray array];
    NSMutableArray *group;
    for (id object in ungroupedItems) {
        if (!group) {
            group = [NSMutableArray arrayWithCapacity:9];
        }
        [group addObject:object];
        if (group.count == 9 || object == [ungroupedItems lastObject]) {
            [groupedItems addObject:group];
            group = nil;
        }
    }
    return [[TLIndexPathDataModel alloc] initWithItems:groupedItems];
}

无需过多详细介绍 TLIndexPathTools 的工作原理(请参阅自述文件),您可以针对TLIndexPathDataModelAPI编写视图控制器代码。因此,当您执行上述映射时,您的视图控制器只需要知道数据模型中的项目是托管对象的数组。

有几个示例项目值得一试:

  1. “核心数据”项目演示核心数据集成
  2. “无结果”项目演示了使用上述委托方法在数据模型包含零项时显示“无结果”行。

需要注意的是,TLIndexPathTools 仅设计为扩展到几千个项目。因此,如果您有一个非常大的数据集,您可能会遇到性能问题。

于 2013-11-13T04:21:00.270 回答
0

我想到了。我只是自定义NSFetchedResultsControllerDelegate. 例如,我定义了自定义NSFetchedResultsChangeInsert的方法NSFetchedResultsChangeDelete案例。didChangeObject

感谢@Duncan Groenewald 的回复。

于 2013-11-14T09:46:19.030 回答