2013-08-31 5 views
2

эй, я застрял с той же проблемой в течение нескольких дней, время для вставки увеличивается постепенно, а в нижних ipad оно также падает с проблемой памяти. Для вставки записей 20k требуется 4-5 минут. efficieny. ? В любом случае я могу это оптимизировать. Пожалуйста, помогите, если сможете.ios Coredata большой набор вставки

+(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; 

}

ответ

3

Это занимает около 4 минут, чтобы хранить записи 20k. Я принес его до 8seconds (это было действительно сложно!) Со следующим кодом:

+(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; 

}

на каждые 1000 записей я сохранить в этом контексте, после сохранения сброса и получить новый контекст снова :

[thisContext reset]; 
     thisContext=[self getInsertContext]; 
+0

Я думаю, что ваше повышение производительности - это, прежде всего, менеджер 'nil' undo. Это стандартная практика в случае крупных импортов с детскими контекстами (это упоминается в Руководстве по программированию основных данных). – Mundi

+0

Да, это главное. Вышеприведенный код повышает производительность, поскольку большие данные не раздуваются в одном контексте. –

-1

Вы должны поставляться с этой БД уже созданы в связке.

+0

Получаю данные из запроса в виде JSON. Я нашел решение ниже. –

1

В принципе нет никаких проблем с вставкой исходных данных в базу данных при запуске. Копирование готовых баз данных Core Data, безусловно, быстро, но также громоздко готовится и обновляется.

Вот некоторые идеи:

1) Переписать для цикла, так что вы перебирает партии и имеете внутренний контур Перебор записей. Вставьте обе петли в отдельные скобки @autoreleasepool.

2) Рассмотрите возможность изменения valueForKey на objectForKey при извлечении значения из словаря. Разница тонкая, но важная.

3) Уточните, где исходит ваш thisContext. Это основной контекст приложения или детский контекст. В последнем случае сохранение фактически не записывается в базу данных до тех пор, пока родитель не сохранит.

4) Рассмотрите API-интерфейс performBlock контекста управляемого объекта, который дает дополнительную изоляцию потока и памяти.

+0

Это увеличит минимальную производительность. Однако я понял это, ответил ниже. –

Смежные вопросы