问题
I am having performance issues while retrieving data from the database.
Right now, this is how I do it.
+(NSMutableArray *) searchObjectsInContext: (NSString*) entityName : (NSPredicate *) predicate : (NSString*) sortKey : (BOOL) sortAscending
{
i3EAppDelegate *appDelegate = (i3EAppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
[request setEntity:entity];
[request setFetchBatchSize:5];
//[request setFetchLimit:10];
[request setReturnsObjectsAsFaults:NO];
// If a predicate was passed, pass it to the query
if(predicate != nil)
{
[request setPredicate:predicate];
}
// If a sort key was passed, use it for sorting.
if(sortKey != nil)
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:sortAscending];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
}
NSError *error;
NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
// NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
[request release];
//[context release];
appDelegate = nil;
return [mutableFetchResults autorelease];
}
Is there any other way to perform the same operation but in a faster way?
If so, it would be great if someone could help me out in this.
回答1:
There are a few issues:
- You do not have a predicate. Therefore you are retrieving the entire table. That is probably your single biggest issue.
- You are loading all of the full objects on retrieval. This is going to slow things down considerably. If you do not need the entire objects realized then I would suggest turning
-setReturnsObjectsAsFaults:
back on. - The setting of
-setFetchBatchSize:
is probably not having the effect you are expecting. If you want to limit the number of results returned use-setFetchLimit:
- Making a
-mutableCopy
of theNSArray
results has no value. I suspect you got that from a book and recommend you stop doing it.
回答2:
Ask yourself a couple of questions about your data requirements.
Do you need access to all the results at once? If you only need a small number at a time you could retrieve only the NSManagedObjectID
's:
[request setResultType:NSManagedObjectIDResultType];
This will be very quick and give you a sorted list, but you'll have to retrieve the actual data as required.
If you need the data a bit faster you could retrieve faulted NSManagedObject
's
[request setIncludesPropertyValues:NO];
This will allocate the objects in advance, but won't fetch the actual data until you request it.
Alternatively do you need to perform the sort as part of the fetch, or if could you somehow do it quicker once the objects are in memory?
It is worth creating yourself a test harness and trying the various options to see which are most suitable for your application.
来源:https://stackoverflow.com/questions/7628700/alternate-way-to-retrieve-data-from-core-data-database-ios