Основные данные iOS10: viewContext не получает обновления от newBackgroundContext() с помощью NSFetchResultController

В моем приложении у меня есть NSFetchResultController для загрузки объектов Core Data в UITableView. Запрос на выборку, связанный с этим FRC, использует новое свойство viewContext, доступное для NSPersistentContainer (iOS10).

Когда я выбираю ячейку, я передаю объект Core Data в новый ViewController. Этот новый VC по-прежнему использует viewContext. Из этого ViewController я могу обновить объект Core Data из ViewControllers, представленный модально. Для этого я использую newBackgroundContext() для модальных ViewControllers. Я могу сохранить объект Core Data Update без каких-либо проблем.

Проблема заключается в том, что FRC не обновляется автоматически с помощью объекта Core Data Update из фонового контекста. Это как если бы viewContext не получал и не обрабатывал обновления объектов Core Data.

Если я установил automaticallyMergesChangesFromParent в true для viewContext (приложение широкий), FRC получает обновленный объект Core Data, когда я сохраняю фоновый контекст. По моему мнению, viewContext должен автоматически управлять слиянием данных. Документация описывает viewContext с: "Этот контекст настроен на то, чтобы быть поколением и автоматически потреблять уведомления о сохранении из других контекстов".

Можете ли вы пояснить, как обрабатывать различные контексты с помощью NSFetchResultController?

Спасибо, Axel

Ответы

Ответ 1

Вы видите правильное поведение. Если вы хотите, чтобы ваш viewContext автоматически выбирал изменения из других контекстов, в том числе созданные из newBackgroundContext(), вам нужно установить automaticallyMergesChangesFromParent в true.

Я согласен с тем, что документы сбивают с толку в этой точке, "... и автоматически потребляют сохраненные уведомления из других контекстов".

Ответ 2

Я не сталкивался с этим напрямую, но ваша проблема поражает меня как нечетную, если newBackgroundContext на самом деле был слоем под viewContext, поскольку любое сохранение из нового контекста только обновило бы viewContext, что также должно было бы сделать свое сохранить, чтобы получить изменения в постоянном хранилище (который, как вы говорите, происходит правильно). Основываясь на этом подозрении, я посмотрел документы разработчиков, где Apple говорит:

Вызов этого метода (newBackgroundContext()) заставляет постоянный контейнер создавать и возвращать новый NSManagedObjectContext с параметром concurrencyType, заданным для privateQueueConcurrencyType. Этот новый контекст будет напрямую связан с NSPersistentStoreCoordinator и будет автоматически загружать широковещательные передачи NSManagedObjectContextDidSave.

Таким образом, это не было бы в отношениях родитель-ребенок с viewContext. Основываясь на руководстве, кажется, что новый контекст будет уведомлен об изменениях старым, но не наоборот, поэтому вам нужно будет обновить объект viewContext при изменении нового контекста, который вы можете делать программно, если сможете отслеживайте это в своем коде или, возможно, используйте одно из уведомлений об изменениях в NSManagedObjectsContext, чтобы вызвать действие.

Ответ 3

Автоматически объединять изменения с родительских потребностей для установки в viewContext следующим образом:

persistentContainer.viewContext.automaticallyMergesChangesFromParent = true