Отказ
Даниэль Дикисон ответ - это правильный ответ. Я только предлагаю здесь некоторые дополнительные детали и объяснения, так как некоторые из этих шагов не тривиальны.
Использование 2 различных контекстов управляемых объектов - правильное решение
Пользовательский интерфейс MOC:
lazy var mainQueuemanagedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(
concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
Транспорт, загрузка, фон MOC:
lazy var transportManagedObjectContext:NSManagedObjectContext = {
let coordinator = CoreDataStack.sharedInstance.persistentStoreCoordinator
let managedObjectContext = NSManagedObjectContext(
concurrencyType: .PrivateQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
Использование фонового MOC для фоновых операций:
(например, новые данные были загружены и сохранены)
transportManagedObjectContext.performBlockAndWait({ () -> Void in
// ...add, change, delete objects, then save
try transportManagedObjectContext.save()
})
Применить Даниэль Дикисон 'ответ на фоновый контекст управляемого объекта в соответствии с документацией Apple :
// Broadcast NSManagedObjectContextDidSaveNotification
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "mocDidSaveNotification:",
name: NSManagedObjectContextDidSaveNotification,
object: self.transportManagedObjectContext)
func mocDidSaveNotification(notification:NSNotification)
{
mainQueuemanagedObjectContext.performSelectorOnMainThread(
"mergeChangesFromContextDidSaveNotification:",
withObject: notification,
waitUntilDone: true)
}
Примечание: Я обычно предпочитаю использовать performBlockAndWait()
и waitUntilDone: true
, если я не уверен, что не ждет не приведет к условиям гонки. Я приглашаю вас тщательно протестировать вашу заявку, если вы решите не ждать. Я позволю себе заставить фоновый поток ждать пользовательского интерфейса, но никогда наоборот.
Прослушивание из потока пользовательского интерфейса
NSFetchedResultsController
must use MainQueueConcurrencyType
Context of Managed Object.
let fetchedResultsController = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: mainQueuemanagedObjectContext,
sectionNameKeyPath: "yourKey",
cacheName: nil)
Ваш NSFetchedResultsController
освобождается от фонового контекста управляемого объекта и получает controllerWillChangeContent
, didChangeObject
и т. Д. после слияние было завершено.