NSConstraintConflicts происходят при сохранении, даже если установлена ​​политика слияния - PullRequest
0 голосов
/ 14 мая 2019

У меня есть основной стек данных, который только явно использует основной контекст и вносит изменения только в / создает постоянные объекты в блоке context.performAndWait.Если мне когда-либо понадобится фоновый контекст, я всегда использую следующий блок кода:

persistentContainer.performBackgroundTask()
{context in
    context.performAndWait
    {
        defer
        {
            context.save()
            persistentContainer.context.save()
        }
        //make changes here
    }
} 

Политика слияния основного контекста устанавливается при создании persistentStore, равной NSOverwriteMergePolicy, которая при сохранении фонового контекстаЯ ожидал перезаписать все «старые» объекты в главном контексте любыми «новыми» объектами, созданными в фоновом контексте.Вместо этого происходит ошибка NSConstraintConflict, потому что фоновый контекст использует политику слияния по умолчанию (не знаю почему, я ожидал, что он унаследует политику слияния основного контекста). Когда я явно устанавливаю политику слияния фонового контекстаЯ получаю дубликаты объектов, которые не должны быть дубликатами в соответствии с установленными мною ограничениями.В этом случае атрибут clientID должен быть уникальным для любого данного объекта Client.

Мне кажется, что я как-то неправильно объединяю контексты.Теперь я делаю это, просто сохраняя фоновый контекст, а затем основной контекст, более или менее, как показано выше.Но если я не произвел слияние должным образом, почему возникла ошибка ограничения, если в фоновом контексте есть объекты, которые имеют те же атрибуты, что и объекты в основном контексте?И почему дубликаты появляются, когда я делаю запрос на выборку основного контекста?

У меня всего лишь два месяца на использование основных данных, и все, что я знаю, получено из документации или здесь, так что яконечно, есть кое-что, о чем я просто не знаю.Есть идеи, что я делаю не так?

1 Ответ

0 голосов
/ 14 мая 2019

Оказывается, я не установил ограничение для объекта, дубликаты которого я видел.Установка ограничения избавила от дублированных объектов.

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

class MergePolicedNSPersistentContainer: NSPersistentContainer
{
    override func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void)
    {
        super.performBackgroundTask()
        { context in
            context.mergePolicy = PersistenceManager.shared.mergePolicy
            //PersistenceManager is a custom singleton class where I do lots of custom coreData stuff, mostly sanity checks and locks. In this case I use it to store a merge policy instance to use here.
            block(context)
        }
    }
}

При инициализации моего хранилища данных в пользовательском классе PersistenceManager:

lazy var persistentContainer: MergePolicedNSPersistentContainer = {

    let container = MergePolicedNSPersistentContainer(name: "MyAppDataModel")
    container.loadPersistentStores()
    { (storeDescription, error) in

        container.viewContext.mergePolicy = self.mergePolicy

        if let error = error as NSError?
        {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    }
    return container
}()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...