Могу ли я вызвать или запустить основной контекст Core Data (viewContext) из фонового потока?

#ios #swift #core-data

#iOS #swift #core-data

Вопрос:

В своем приложении я использую только основной контекст Core Data. Я знаю, что основной контекст может быть запущен только основным потоком. Однако, когда я обновляю основной контекст из фонового потока, я не сталкиваюсь с каким-либо сбоем.

     //Cloudkit operation
 let zoneOperation = CKFetchRecordZoneChangesOperation(recordZoneIDs: zonesIDs, optionsByRecordZoneID: [zonesIDs[0]: options])

 zoneOperation.recordChangedBlock = { (record) in

// This is background thread
 print("Record has changed")
    let date = record["date"] as! Date

//Fetching Managed Object Context from Coredata (Main Context)
if let migraine = migraine(OnDate: date, inContext: self.persistentContainer.viewContext) {
migraine.date = date
saveData(inContext: self.persistentContainer.viewContext)
}
}
  

Как я могу выполнить сохранение основного контекста Coredata внутри фонового потока без сбоев?

Комментарии:

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

2. Спасибо за ответ. Значит ли это, что я могу вызвать или запустить основной контекст Core Data (viewContext) из фонового потока?

3. Не могли бы вы хотя бы сделать отступ в своем коде

4. все дело в несоответствии, пока его нет, основной или дополнительный поток не имеет значения. основной поток — это поток с высоким приоритетом. Присвоение имени этому потоку пользовательского интерфейса ничего не меняет

Ответ №1:

Используйте perform(_:) или performAndWait(_:) , чтобы убедиться, что изменения в контексте происходят в потоке, к которому принадлежит контекст.

 persistentContainer.viewContext.performAndWait { 
  self.saveData(inContext: persistentContainer.viewContext)
}
  

Вы также можете сделать что-то подобное с

 persistentContainer.performBackgroundTask { context in
  // Do stuff on this context and arrange for the changes
  // to be merged back to the view context. 
}