我正在使用NSFetchedResultsController
从Core Data结构中提取几千个结果并将其显示在UITableView
中。我有一些可用的选项,用谓词执行提取并显示更新的数据,例如按关键字搜索,按作者排序等。
我想在显示之前随机随机播放订单。我创建了一个NSArray
类别,其shuffle
方法运行正常,但在[self.fetchedResultsController fetchedObjects]
上调用该方法无效,数据保持不变。我假设这是因为fetchedObjects
是readonly
,而且我需要复制。
我已经制作了这个副本,但我遇到的障碍是让新阵列与fetchedObjects
阵列和平共存。我可以转到各种详细视图并修改内容,因此我试图确定如何使fetchedObjects
和我的shuffledFetchedObjects
数组保持同步,即使它们的内容顺序不同。
这是我简单的小shuffle
类别:
- (NSArray *) shuffle {
NSMutableArray *tmp = [NSMutableArray arrayWithArray: self];
for (int i = [tmp count] - 1; i > 0; i--) [tmp exchangeObjectAtIndex: arc4random() % (i + 1) withObjectAtIndex: i];
return [NSArray arrayWithArray: tmp];
}
我有什么选择来实现这个目标?
答案 0 :(得分:2)
无法修改获取的结果控制器(FRC)的fetchedObjects
。您可以使用随机索引将FRC行号映射到表视图行号,而不是对提取的对象进行洗牌,反之亦然。
但是如果你真的不需要FRC的更改跟踪功能,那么更容易进行简单的提取:
NSArray *results = [context executeFetch:request error:&error];
洗牌结果:
NSArray *shuffledResults = [results shuffle];
并在数据源方法shuffledResults
和numberOfRows...
中使用cellForRow...
。
然后你不必保持任何同步。
更新:如果你有部分,那么你需要FRC,并且需要一个数组(1. level是节号,2。对行号进行调整)。你可以像这样填写:
// ... after [frc performFetch:&error] ...
self.dataSource = [NSMutableArray array]; // a NSMutableArray property of your view controller
for (NSUInteger section = 0; section < [[frc sections] count]; section++) {
NSArray *objects = [[frc sections][section] objects]; // all objects of this section
[self.dataSource addObject:[objects shuffle]];
}
然后,在cellForRowAtIndexPath
中,您可以像这样访问数组:
NSManagedObject *obj = self.dataSource[indexPath.section][indexPath.row];
(一种完全不同的方法是向实体添加属性“randomOrder”,为每个对象分配随机数,并将“randomOrder”的排序描述符添加到获取请求。)
答案 1 :(得分:1)
我设法通过使用shouldShowShuffled
布尔值来解决问题,我根据选择的过滤器来打开和关闭。如果它已转为ON
,我会显示我的FRC结果副本的结果,这些结果会被洗牌。如果它已转为OFF
,我会直接从FRC显示fetchedObjects
。
我在更新fetchedObjects
数组时随时更新混洗数组,因此它始终是最新的。