2015-12-23 47 views
1

我正在尝试制作应用程序,需要从CoreData中获取N个随机对象。Swift + CoreData。从数据库中获取N个随机对象。 N << size(DB)

问题是数据库的大小远远大于我想要获取的对象的数量。因此,最好有一种方法不会影响数据库中的所有记录。

是否可以在不向数据库添加额外字段的情况下实现这一点(例如,id)?

我想要接收不同的请求响应,所以选项“预先使用一些随机函数排序”不起作用。

回答

2

一个接一个取物体的问题可能是性能问题。取决于n的大小,这可能不会缩放。

相反,您可以利用Core Data在处理大量对象时非常高效的事实。由于称为“错误”的机制,您可以获取数以万计的对象而不会有太大的内存占用。

因此,我建议您获取所有对象,并从结果中挑选出一些。

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Response"]; 
NSArray *all = [managedObjectContext executeFetchRequest:request error:nil]; 

NSMutableArray *pickedAnswers = [NSMutableArray array]; 
int remaining = 10; 

if (all.count < remaining) { /* abort */ } 
while (remaining > 0) { 
    Response *response = all[arc4random_uniform(all.count)]; 
    if (![pickedAnswers containsObject:response]) { 
     [pickedAnswers addObject:response]; 
     remaining--; 
    } 
} 

注意,另一个优雅的答案将是第一洗牌阵列(如所示here然后挑选第一n元件)。这将消除通过while循环的不必要的运行。

3

计数的所有记录第一:

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"<your entity name>"]; 
NSUInteger count = [context countForFetchRequest:request error:NULL]; 

使用fetchOffset

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"<your entity name>"]; 
request.fetchLimit = 1; 
request.fetchOffset = arc4random_uniform(count); 
NSArray *result = [context executeFetchRequest:request error:NULL]; 

重复N次,从而获得所需的对象的数量。

相关问题