Ответ 1
MagicalRecord использует дочерний контекст при выполнении работы в фоновом режиме. Это отлично подходит для небольших изменений, но при импорте больших объемов данных будет создано чрезмерное блокирование основных потоков.
Способ сделать это - использовать параллельный NSManagedObjectContext и объединить себя с уведомлением NSManagedObjectContextDidSaveNotification
и методом mergeChangesFromContextDidSaveNotification
. См. Тесты производительности здесь: http://floriankugler.com/blog/2013/5/11/backstage-with-nested-managed-object-contexts
При сохранении вложенных контекстов все необходимо скопировать в родительский контекст. В противоположность этому объекты, которые не были выбраны (в контексте, в которые вы сливаетесь), не будут объединены с помощью mergeChangesFromContextDidSaveNotification
. Это то, что делает его быстрее.
У вас могут возникнуть проблемы, если вы хотите сразу же отобразить эти результаты после сохранения в партиях и с помощью NSFetchResultsController. См. Следующий вопрос для решения: NSFetchedResultsController с предикатом игнорирует изменения, объединенные из другого NSManagedObjectContext
Для получения дополнительных рекомендаций по производительности рассмотрите этот вопрос: Внедрение быстрого и эффективного импорта основных данных на iOS 5
Создайте свой собственный контекст.
NSManagedObjectContext *importContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[importContext setPersistentStoreCoordinator:yourPersistentStoreCoordinator];
[importContext setUndoManager:nil]; // For importing you don't need undo: Faster
// do your importing with the new importContext
// …
NSError* error = nil;
if(importContext.hasChanges) {
if(![importContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
Убедитесь, что вы прослушиваете сохранение контекстов управляемых объектов.
[[NSNotificationCenter defaultCenter]
addObserver:singleton
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification object:nil];
В контекстеDidSave: вы сами сгенерируете изменение.
- (void) contextDidSave:(NSNotification*) notification
{
if(![notification.object isEqual:self.mainContext]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.mainContext mergeChangesFromContextDidSaveNotification:notification];
});
}
}