我可以使用 NSFetchedResultsController 将 n 条记录映射到 1 个表视图行吗?
Posted
技术标签:
【中文标题】我可以使用 NSFetchedResultsController 将 n 条记录映射到 1 个表视图行吗?【英文标题】:May I map n records to 1 table view row with NSFetchedResultsController? 【发布时间】:2013-11-12 23:08:07 【问题描述】:在我的应用程序中,我使用 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);
添加第一条记录就OK了。但是当我添加第二条记录时,出现错误:
-[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 移出)。与 userInfo (null)
这是否意味着 NSFetchedResultsController 仅支持 1 记录到 1 行的映射?还是有更好的方法来完成它?
【问题讨论】:
您可能需要自定义委托方法,该方法将尝试将项目添加到 tableView 以响应您添加新记录。您可能需要考虑创建与 9 条记录有关系的其他分组实体,并在 fetchedResultsController 中选择它,然后只需自定义 tableView 单元以显示您可以从分组实体关系属性中检索的相关 9 条记录。我会先尝试自定义委托方法,以便它们匹配自定义数据源。 【参考方案1】:如果您可以使用NSFetchedResultsController
替代方案,那么使用TLIndexPathTools 中的TLIndexPathController
类很容易做到这一点。它将所有五个NSFetchedResultsController
委托方法滚动到一个didUpdateDataModel
方法中,因此通常更易于使用。但更符合您的需要,它提供了一个willUpdateDataModel
委托方法,可让您将获取的托管对象映射到任意数据模型。这是一个将对象映射为九个组的示例:
- (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 的工作原理(参见 readme),您可以针对 TLIndexPathDataModel
API 编写视图控制器代码。因此,当您进行上述映射时,您的视图控制器只需要知道数据模型中的项目是托管对象的数组。
有几个示例项目值得一试:
-
“Core Data”项目演示了 Core Data 集成
“无结果”项目演示了使用上述委托方法在数据模型包含零项时显示“无结果”行。
需要注意的是,TLIndexPathTools 仅设计为可扩展到几千个项目。因此,如果您有一个非常大的数据集,您可能会遇到性能问题。
【讨论】:
【参考方案2】:我想通了。我只是自定义NSFetchedResultsControllerDelegate
的方法。例如,我定义了didChangeObject
方法的自定义NSFetchedResultsChangeInsert
、NSFetchedResultsChangeDelete
案例。
感谢@Duncan Groenewald 的回复。
【讨论】:
以上是关于我可以使用 NSFetchedResultsController 将 n 条记录映射到 1 个表视图行吗?的主要内容,如果未能解决你的问题,请参考以下文章
我可以同时使用 UIPageViewControllers 吗?
一旦我可以使用 XMPP 列出用户,我如何在这些用户之间实现聊天?
我可以在 ScriptEditor、SharePoint 中使用 Json 吗?