2016-02-06 2 views
1

Я имею дело со сценарием, где есть объекты, которые, если они будут удалены, приведут к экспоненциальному количеству удалений через отношения каскада-удаления. Таким образом, удаление 20 из этих объектов может привести к уничтожению ~ 3000 объектов. Это может привести к очень медленным экономиям, если они выполняются с основным контекстом.Обработка тяжелых удалений/вставок в данных ядра

Для борьбы с этим, я создаю «работник» контекст, который использует то же постоянное хранилище в качестве основного контекста, внесение изменений там, затем сохранить контекст уборщицы и слияние этих изменений с основным контекстом:

NSManagedObjectContext *workerContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 

workerContext.persistentStoreCoordinator = mainContext.persistentStoreCoordinator; 

[notificationCenter addObserver:self selector:@selector(workerContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:workerContext]; 

// Here I do a 'superficial' deletion on the main context, so the UI updates, 
// but do the actual deletion on the worker context. Then I save the worker context: 

[workerContext save:nil]; 

// Which fires spawnedWorkerContextDidSave:, where I merge changes to the main context: 

[mainContext performBlockAndWait:^{ 
    [mainContext mergeChangesFromContextDidSaveNotification:notification]; 
}]; 

Мои вопросы (вопросы): какой наиболее распространенный способ обработки таких больших партий делегирования? Есть ли подводные камни для моего подхода выше? Кроме того, слияние приводит к небольшому отставанию основного потока, но ничего не произошло, когда я делал удаления и сохранял основной поток.

+0

попробуйте использовать GCD не в основной теме. –

+0

@SunilSingh Вот что я здесь делаю. Рабочий контекст использует собственный поток. – mattsven

ответ

1

Подходит к удалению данных через второй контекст.

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

Если вы обнаружили, что задержка, сменяющая изменения в основном потоке, является проблемой, вы можете вместо этого просто сбросить основной контекст. Недостатком является то, что ваше приложение должно восстановить все свои данные. Вы могли бы, например, предупредить о пожаре, чтобы предупредить разные части приложения о том, что сброс будет: а) произойдет, и б) произошло.

И, наконец, теперь в базе данных ядра есть API для выполнения больших удалений в фоновом режиме, не вытягивая данные в память. Главное, что вы должны быть осторожны, чтобы объединить удаленные объекты самостоятельно, потому что контекст не будет знать, что они были удалены.

+0

Спасибо Дрю! Я дам ваши предложения попробовать, особенно prefetch. – mattsven

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