#ios #core-data #nsfetchedresultscontroller
Вопрос:
Я пытаюсь импортировать большой набор данных (150 000 записей) по сети в хранилище основных данных SQLite. Текущие требования заключаются в том, чтобы непрерывно загружать эти данные пакетами (по 100 записей за раз), сохранять их и как можно скорее отображать в виде таблицы для прокрутки.
Мой класс поставщика данных предоставляет контекст представления для отображения и использует фоновый контекст для импорта данных. Один и тот же фоновый контекст повторно используется при каждом импорте пакета и сбрасывается перед следующим. Инициализатор для класса поставщика выглядит примерно так:
init(persistentContainer: NSPersistentContainer) {
self.persistentContainer = persistentContainer
viewContext = persistentContainer.viewContext
viewContext.automaticallyMergesChangesFromParent = true
viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
backgroundContext = persistentContainer.newBackgroundContext()
backgroundContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
}
Функция импорта выглядит следующим образом:
func importBatch(_ batch: [JsonData]) {
backgroundContext.perform {
for data in batch {
let newObject = NSEntityDescription.insertNewObject(forEntityName: "Entity", into: backgroundContext)
try! newObject.update(with: data)
}
if backgroundContext.hasChanges {
try! backgroundContext.save()
backgroundContext.reset()
}
}
}
Для отображения я в настоящее время использую контроллер результатов выборки с размером пакета выборки в запросе на выборку. Я замечаю, что, начиная примерно с 10 000 импортированных записей, пользовательский интерфейс в табличном представлении начинает заикаться. Основной причиной, по-видимому, является слияние в контекст представления. При слиянии вручную (т. Е. Когда viewContext.automaticallyMergesChangesFromParent = false
это происходит здесь:
@objc func backgroundContextDidSave(_ notification: Notification) {
self.viewContext.perform {
self.viewContext.mergeChanges(fromContextDidSave: notification)
}
}
Учитывая текущие требования, могу ли я что-нибудь сделать для решения этой проблемы? Тем временем я попробовал следующее, что дает некоторые преимущества, но не решило основную проблему:
- Постоянное отслеживание истории: здесь я попытался объединиться с контекстом представления только каждые 10 пакетов. Более плавная прокрутка, но более длительные паузы при слиянии
- Пакетные вставки: имеет лучшую производительность при сохранении, но тот же пользовательский интерфейс заикается при объединении