ios Coredata large set insert

眉间皱痕 提交于 2019-12-11 00:09:47

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!