Это похоже на элементарный вопрос о базовых данных, но я не смог найти четкого ответа в документах Apple, в StackOverflow или в какой-либо из нескольких книг, с которыми я ознакомился.
Этодля одного NSPersistentContainer
на iOS.Ничего особенного, кроме того, что задействовано несколько NSManagedObjectContext
объектов.
Чего я (думаю, я) хочу:
Пользовательский интерфейс отражает состояние основного NSManagedObjectContext
(то есть тот, который имеет mainQueueConcurrencyType
).Обновления объектов Core Data выполняются в фоновом контексте.Когда фоновый контекст сохранен, изменения Базовых данных распространяются на основной контекст.Пользовательский интерфейс затем уведомляется об измененных объектах и соответствующим образом обновляет отображение.
Почему это кажется трудным / неудобным / невозможным:
В настоящее время я использую automaticallyMergesChangesFromParent
восновной контекст.Он работает нормально, в том смысле, что фоновые изменения становятся доступными для основного контекста.Если вы запросите объект, которого еще нет в памяти, вы получите обновленную версию.
Однако существующие объекты в основном контексте (то есть объекты, которые уже были прочитаны из резервного хранилища) необновлять при объединении изменений из фонового контекста.Насколько я понимаю, это фундаментальный принцип Core Data;Вы должны обновить объекты, чтобы увидеть обновления.Отлично.
Проблема, однако, в том, что уведомления NSManagedObjectContextObjectsDidChange
основаны на изменениях живых объектов.Основной контекст может объединять изменения из 100 различных фоновых контекстов и никогда не выдавать уведомление об обновлении, поскольку эти уведомления создаются только для живых объектов - и живые объекты не обновляются автоматически.
Если вы обновляете объекты восновной контекст (с mainContext.refresh(obj, mergeChanges: true)
), вы получаете уведомление об изменении для каждого объекта.Однако тип изменения всегда «обновляется», независимо от того, было ли какое-либо свойство объекта фактически изменено фоновым контекстом.Другими словами, к тому времени, когда изменения были объединены с основным контекстом, вся подробная информация об обновлении была утеряна, и восстановить ее невозможно без проведения собственных сравнений полей с полями и отношений с нуля с нуля.,(Этот процесс также превращает все ваши объекты обратно в неисправности, что не является оптимальным.)
Я вижу, что есть возможный выход из этой чаще, вручную управляя каждым фоновым контекстом и слушая его NSManagedObjectContextDidSave
уведомления, а затем вручную сопоставляют идентификаторы объектов с основным контекстом и обновляют только те объекты, которые фактически были обновлены.Я не уверен точно, как каждый учитывает удаления в этом рабочем процессе, все же.И кажется, что это много ручного труда.
Неужели не существует стандартного надежного способа сбора информации такого рода при использовании нескольких контекстов?