Search code examples
iosobjective-ccore-datansarraynsfetchrequest

Core Data object rank (slow)


I need to get the rank of an object between thousands of other objects in Core Data. Right now, here is my code:

- (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"
}

The problem with this code is that getting the index of an object on a big NSArray (thousands of objects) can be very slow (possibly several seconds). Is there a way to catch the rank of an object directly in Core Data without having to use an NSArray (ie avoid accessing the device memory)?

Thanks.


Solution

  • If you perform a Fetch with a NSPredicate asking for all entries that are greater than self.record.date, then the rank of the record is the number of entries returned plus 1

    Then perform the fetch you already have to get the total