Search code examples
xcodecore-datanspredicatensfetchrequest

Is there anything bad about reusing an NSFetchRequest for several different fetches with Core Data?


My question: Is there anything bad about reusing an NSFetchRequest for several different fetches with Core Data?

Example code:

NSFetchRequest *request = [[NSFetchRequest alloc] init];

NSEntityDescription *logEntity = [NSEntityDescription entityForName:@"LogEntry" inManagedObjectContext:context];
[request setEntity:logEntity];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"dateTimeAction" ascending:NO]; // ascending NO = start with latest date
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"status == %@",@"op tijd"];
[request setPredicate:predicate];
[request setFetchLimit:50];

NSError *error = nil;
NSInteger onTimeCount = [context countForFetchRequest:request error:&error];

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"status == %@",@"uitgesteld"];
[request setPredicate:predicate1];
[request setFetchLimit:50];

NSInteger postponedCount = [context countForFetchRequest:request error:&error];

NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"status == %@",@"gemist"];
[request setPredicate:predicate2];
[request setFetchLimit:50];

NSInteger missedCount = [context countForFetchRequest:request error:&error];

Solution

  • It's not a problem, but in the example given it's not gaining you much (just some code brevity.) The most expensive part of creating a fetch request is parsing the predicate format string.

    If the code you've given is called frequently, and you're looking to speed it up, here are some ideas to try:

    • Create all the predicates and fetch request just once: maybe in a dispatch_once() block and storing them statically; or in the constructor and stored in object fields
    • Don't specify sort descriptors, since order doesn't matter if you only care about the count
    • If the actual predicates will be more complex or flexible than shown, create one general template predicate with substitution variables, and use predicateWithSubstitutionVariables: to generate specified copies.
    • For even more code brevity, define that template in the object model using the model editor, and use fetchRequestFromTemplateWithName:substitutionVariables: to create fetch requests.

    I can gin up some sample code if you like.