CoreData: удаление предварительной выборки распространения не удалось с помощью NSCKImportOperation

Я тестирую CoreData+CloudKit, т. е. использую NSPersistentCloudKitContainer, который обрабатывает всю связь с iCloud.
Когда я запускаю приложение, CoreData автоматически синхронизируется с iCloud, т. е. (помимо прочего) вставленные или обновленные записи импортируются в CoreData. Ни одна запись никогда не удаляется.
Мои тесты выполняются на симуляторе.

Моя первая попытка состояла в том, чтобы использовать только viewContext. Чтобы объединить удаленные изменения в этот контекст, я установил

viewContext.automaticallyMergesChangesFromParent = true

Кроме того, я использую отслеживание истории как предложено Apple, за исключением того, что обработка истории также использует viewContext, а не новый фоновый контекст.
Это сработало нормально, за исключением ожидаемой блокировки пользовательского интерфейса с помощью viewContext.

Таким образом, моя вторая попытка состояла в том, чтобы обработать историю фоновым контекстом (как было предложено Apple).
Теперь повторно регистрируется следующая ошибка (очевидно, навсегда):

CoreData: удалить предварительную выборку распространения не удалось, за исключением: объект запроса на выборку 0x6000017a2050 «NSCKImportOperation», по-видимому, относится к модели NSManagedObjectModel, отличной от модели этого контекста.

Эта ошибка регистрируется даже после того, как я удалил все записи iCloud на панели инструментов и удалил приложение из симулятора.
Я использую только один NSManagedObjectModel с отношениями, но все отношения имеют правило удаления «Нет действий».

Чтобы проверить причину этой ошибки, я установил точку останова во время выполнения, и приложение остановилось со следующей трассировкой стека:

введите здесь описание изображения

Я должен отметить, что ошибка исчезает, если я устанавливаю

viewContext.automaticallyMergesChangesFromParent = false

но мне, конечно, нужно автоматическое слияние для правильной работы.

Мои вопросы:
Это действительно ошибка? (В логах написано "похоже...").
В чем может быть причина и как этого избежать?

PS: есть много других сообщений, связанных с предварительной выборкой CoreData, но я не нашел ни одного, относящегося к CoreData+CloudKit.


person Reinhard Männer    schedule 01.11.2020    source источник


Ответы (1)


Я думаю, что причиной была неправильная конфигурация моего фонового контекста. Он был настроен на сохранение всех зарегистрированных объектов. Как только я прокомментировал соответствующий код, ошибка исчезла:

private (set) lazy var backgroundContext: NSManagedObjectContext! = {
    let context = persistentContainer.newBackgroundContext()
    context.name = "backgroundContext"
    
    // For possible merge policies see <https://developer.apple.com/documentation/coredata/nsmergepolicy/merge_policies>
    context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    
    /*
    CAUTION: DO NOT ENABLE THE FOLLOWING STATEMENT:
    context.retainsRegisteredObjects = true
    If enabled, the following error is reported indefinitely:
    ShopEasy[20204:2672392] [error] CoreData: Delete propagation prefetching failed with exception: 
    The fetch request's entity 0x600003764630 'NSCKImportOperation' appears to be from a different NSManagedObjectModel than this context's
    */
            
    // Pin the context to the current generation token and set it to keep itself up to date with local changes.
    context.automaticallyMergesChangesFromParent = true
    context.performAndWait {
        do {
            try context.setQueryGenerationFrom(.current)
        } catch {
            fatalError("###\(#function): Failed to pin viewContext to the current generation: \(error)")
        }
    }
    return context
}()
person Reinhard Männer    schedule 01.05.2021