问题
hey i am stuck with the same problem for days , time for insert increases gradually and in lower ipads it also crashes with memory problem .To insert 20k records it takes 4-5 minutes.Will background thread improve efficieny. ? Is there anyway i can optimize this. Please help out if you can.
+(BOOL) addObjectToProfessionalsDBWithDict:(NSArray*)profArray{
if (!([profArray count]>0 && profArray )) {
return NO;
}
NSManagedObjectContext *thisContext=[self getManagedObjectContext];
for (int i=0; i<[profArray count]; i++) {
NSManagedObject *professionalDBObject = [NSEntityDescription
insertNewObjectForEntityForName:@"ProfessionalsDB"
inManagedObjectContext:thisContext];//initWithDictionary:objectDict]; NSMutableDictionary * objectDict=[profArray objectAtIndex:i];
[professionalDBObject setValue:[objectDict valueForKey:@"Degree"] forKey:@"degree"];
[professionalDBObject setValue:[objectDict valueForKey:@"First_Name"]
// and 10 more values
if(i%500==0){
NSError *error;
NSLog(@"saved rec nu %d",i);
if (![thisContext save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
return NO;
}
else{
NSLog(@"data saved");
}
[thisContext reset];
}
}
[prefs setInteger:numOfRecords forKey:@"numberOfRecords"];
NSError *error;
if (![thisContext save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
return NO;
}
return YES;
}
回答1:
It was taking around 4 minutes to store 20k records. I have brought it down to 8seconds(it was really tricky!) with the following code:
+(NSManagedObjectContext*)getInsertContext{
NSManagedObjectContext *thisContext=[[NSManagedObjectContext alloc] init];
AppDelegate *delegate=(AppDelegate*)[[UIApplication sharedApplication] delegate];
NSPersistentStoreCoordinator *coordinator = [delegate persistentStoreCoordinator];
[thisContext setPersistentStoreCoordinator:coordinator];
[thisContext setUndoManager:nil];
return thisContext;
}
on every 1000 records i save in this context, after saving reset and get a new context again:
[thisContext reset];
thisContext=[self getInsertContext];
回答2:
There is no problem in principle with inserting the seed data into the database at startup. Copying ready-made Core Data databases is certainly fast, but also cumbersome to prepare and keep updated.
Here are some ideas:
1) Rewrite the for loop so that you iterate through the batches and have an inner loop iterating through the records. Enclose both loops into separate @autoreleasepool
brackets.
2) Consider changing valueForKey
to objectForKey
when retrieving the value from the dictionary. The difference is subtle, but important.
3) Clarify where your thisContext
comes from. Is it the apps's main context or a child context. In the latter case the save does not actually write to the database until the parent also saves.
4) Consider the performBlock
API of managed object context which gives you additional thread and memory insulation.
回答3:
You should ship with this DB already created in your bundle.
来源:https://stackoverflow.com/questions/18550873/ios-coredata-large-set-insert