6

I'm developing and application which needs to check if a string has been saved to the database or not. This may seem an easy operation but it needs half a second to return any response which I think is quite a lot. My question is if there is any way to reduce that time. Thanks for your interest.

This is my current code:

- (BOOL) isDeleted:(int)i {

    NSString *value = [NSString stringWithFormat:@"deleted.*.%i", i];

    MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];

    NSString *entityName = @"Deleted";
    NSEntityDescription *entityDesc = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDesc];

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(deletedpics like %@)", value];
    [request setPredicate:pred];

    NSError *error;
    NSArray *objects = [context executeFetchRequest:request error:&error];

    BOOL returnBool = [objects count] >= 1 ? YES : NO;
    return returnBool;

}
IOS_DEV
  • 949
  • 3
  • 12
  • 33
  • Could you explain the entities and relationships? I do not quite understand the predicate. – Martin R Mar 03 '13 at 20:06
  • There's no relationship between the different entities. Specifically, this entity just contains one attribute which is the one called _deletedpics_. Referring to the predicate, the idea is to check if the picture has been reported as deleted or not. I organize the deleted registers as "deleted.status(variable which I need for other operations).picturenumber". In this function I want to check if a certain picture has been deleted or not without taking in account the status. That's why I used this predicate. I hope it's clearer now. – IOS_DEV Mar 03 '13 at 20:26
  • Try to index that property. What does `@"deleted.*.%i"` mean? – Lorenzo B Mar 03 '13 at 21:11

1 Answers1

6

One optimization is to replace

NSArray *objects = [context executeFetchRequest:request error:&error];

by

[request setFetchLimit:1];
NSUInteger count = [context countForFetchRequest:request error:&error];

if you only want to check for the existence of objects.

But I assume that the main performance problem is the wildcard search with LIKE, which is slower than searching with ==.

Instead of storing the status and the picture number in one attribute as deleted.<status>.<picturenumber> (as you wrote in a comment) it would probably be better to use separate attributes status and picturenumber in the entity.

Then you can search for a picture number with the predicate

[NSPredicate predicateWithFormat:@"picturenumber == %d", i];

which should be much faster. If necessary, you can additionally index that property (as @flexaddicted mentioned in a comment).

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382