2014-02-27 45 views
0

我需要获取核心数据中数千个其他对象之间的对象排名。现在,这里是我的代码:核心数据对象排名(慢)

- (void)rankMethod 
{ 
    //Fetch all objects 
    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Records"]; 
    [fetchRequest setIncludesPropertyValues:NO]; 

    //Sort all objects by date/recent date == better rank 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO]; 
    NSArray *sortDescriptors = @[sortDescriptor]; 
    [fetchRequest setSortDescriptors:sortDescriptors]; 

    //Set all objects in a NSArray 
    NSError *error; 
    NSArray *recordsArray = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    //Get the rank of my object (self.record) in the array 
    NSUInteger recordRank = [recordsArray indexOfObject:self.record] + 1; 

    //Get the count of all objects 
    NSUInteger recordsCount = [managedObjectContext countForFetchRequest:fetchRequest error:&error]; 

    //NSLog my object rank 
    NSLog(@"Rank: #%ld/%ld", (unsigned long)recordRank, (unsigned long)recordsCount); 
    //Console display: "Rank: #4282/5000" 
} 

这段代码的问题是,越来越对象的指数上了一个大的NSArray(成千上万个对象)可能会非常缓慢(可能几秒钟)。有没有办法直接在核心数据中捕捉对象的排名而不必使用NSArray(即避免访问设备内存)?

谢谢。

+0

为什么你需要排名属性?为获取最后插入的对象? –

回答

0

如果您执行NSPredicate的提取请求所有大于self.record.date的条目,那么记录的排名是返回的条目数1

然后执行取回你已经得到总数

1

没有与您计算的几个问题:

  1. 你的“等级”并不稳定。如果有两个对象具有相同的日期,则没有办法决定先出现(一次取第一次可能是第一次,而在另一次取最后一次)...
  2. 如果执行计数请求没有意义你已经获取的对象(只需使用[recordsArray count]
  3. 你取的,而不是只得到对象ID的整个实体(设置读取请求的结果类型:NSManagedObjectIDResultType,并寻找对象ID

所以我的建议是:

  1. 创建“配合你的对象之间的断路器(计数器,creationDate等)
  2. 使用这个谓词[NSPredicate predicateWithFormat:@"date >= %@ AND tieBreaker > %@",self.date,self.tieBreaker]
  3. 取数这个谓词

这样,你只能访问存储一次,不需要查找巨大数组中的对象...