I am learning core data and particularly working on aggregation.
Current what I want to do : count the number of records from the table which is in to-many relations
Jeff LaMarche is just using this as a simple example. In practice, this need is so common that Key-Value Coding has a built in macro to handle it and other common collection operations.
See: The Key-Value Programming Guide: Set and Array Operators
In this case you would use the @count
operator in your predicate.
Of course, hand tuning your own expression gives you fine control over your predicates but the operators handle 80% of such task.
I had to count about 10 000 entities and it slowed down my interface responsiveness a lot while doing it with countForFetchRequest..
Here is a way of doing it wth NSExpression:
- (NSUInteger) unfilteredFCsCount {
// Just the fetchRequest
NSFetchRequest *fetchRequest = [self unfilteredFCsFetchRequest];
[fetchRequest setResultType: NSDictionaryResultType];
// You can use any attribute of the entity. its important, because you are not counting
// the properties, but actually the entities
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"sortIndex_"]; // Does not really matter
NSExpression *maxExpression = [NSExpression expressionForFunction: @"count:"
arguments: [NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName: @"fcCount"];
[expressionDescription setExpression: maxExpression];
[expressionDescription setExpressionResultType: NSInteger32AttributeType];
[fetchRequest setPropertiesToFetch: [NSArray arrayWithObject:expressionDescription]];
NSUInteger fcCount = 0;
NSError *error = nil;
NSArray *results = nil;
results = [self.managedObjectContext executeFetchRequest: fetchRequest error: &error];
KSLog(KSLogLevelDebug, @"unfilteredFCsCount results: %@", results);
if([results count] > 0) {
NSNumber *count = [[results objectAtIndex: 0] objectForKey: @"fcCount"];
fcCount = [count intValue];
}
return fcCount;
}