Я ищу наилучший способ обновления довольно большого набора данных на основе данных на основе фона в фоновом режиме, с минимальным влиянием на пользовательский интерфейс приложения (основной поток).
В этой теме есть хорошие материалы, в том числе:
- Сессия 211 из WWDC 2013 (Оптимизация и отладка производительности основных данных, начиная с 25:30)
- Импорт больших наборов данных из objc.io
- Общие фоновые практики из objc.io (Основные данные в фоновом режиме)
- За кулисами с вложенными управляемыми объектными контекстами
Основываясь на моих исследованиях и личном опыте, лучшим вариантом является эффективное использование двух отдельных стеков данных ядра, которые используют только данные на уровне базы данных (SQLite). Это означает, что нам нужны два отдельных NSPersistentStoreCoordinators
, каждый из которых имеет свой собственный NSManagedObjectContext
. Когда запись в режиме записи включена в базе данных (по умолчанию от iOS 7 и далее), необходимость блокировки можно было бы избежать почти во всех случаях (кроме случаев, когда у нас есть две или более одновременных записей, что маловероятно в моем сценарии).
Для эффективного обновления фона и сохранения памяти необходимо также обрабатывать данные партиями и периодически сохранять фоновый контекст, поэтому грязные объекты сохраняются в базе данных и очищаются от памяти. Можно использовать NSManagedObjectContextDidSaveNotification
, который генерируется в этот момент, чтобы объединить изменения фона в основной контекст, но в целом вы не хотите обновлять свой интерфейс сразу после сохранения партии. Вы хотите подождать, пока фоновая работа будет полностью выполнена, и обновите пользовательский интерфейс (рекомендуется как в сессии WWDC, так и в статьях objc.io). Это фактически означает, что основной контекст приложения остается не синхронизированным с базой данных в течение определенного периода времени.
Все это приводит меня к моему основному вопросу: , что может пойти не так, если я изменил базу данных таким образом, не указав основной контекст на слияние изменений? Я предполагаю это не все солнце, розы.
Один конкретный сценарий, который у меня есть в голове, что происходит, если ошибка должна выполняться для объекта, загруженного в основной контекст, если фоновая операция между удаленным этим объектом из базы данных? Может ли это, например, произойти в представлении таблицы NSFetchedResultsController, которое использует пакетный размер для выборочной выборки объектов в память? I.e., объект, который еще не был полностью извлечен, удаляется, но мы прокручиваем его до точки, где объект должен загружаться. Это потенциальная проблема? Могут ли другие вещи пойти не так? Буду признателен за любые материалы по этому вопросу.