Ложные срабатывания при сбое оптимистичной блокировки основных данных iOS

#ios #core-data

#iOS #core-data

Вопрос:

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

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

Дело в том, что когда я запускаю приложение без -com.apple.CoreData.ConcurrencyDebug 1 переменной среды, я не получаю никаких ошибок от try context.save()

Например, я устанавливаю -com.apple.CoreData.ConcurrencyDebug 1 , затем я выполняю действие, которое что-то делает и сохраняет.

   do {
        try context.save()
     } catch {
        log.error("Delete error: (error)")
  }
 

Я получаю optimistic lock failure исключение на try context.save()

затем я продолжаю возвращать приложение в то же состояние, которое вызвало бы исключение, и запускаю его без -com.apple.CoreData.ConcurrencyDebug 1 и, устанавливая точку останова

   do {
        try context.save()
     } catch {
        log.error("Delete error: (error)") // <--- breakpoint here
  }
 

В отличие от других проблем, с которыми я сталкивался в прошлом, ошибок вообще нет. У меня нет никакой информации о причине блокировки. Может быть много чего не так, но я не могу понять, что именно это портит в этой возможности.

Я много искал в Google, и там не так много подробностей о том, как получить значимую информацию из исключения оптимистичной блокировки.

Комментарии:

1. В прошлый раз, когда я гуглил сбой оптимистичной блокировки основных данных , я получил много советов, я думаю, что это даже в документации Apple, установить недвусмысленную политику слияния в контексте управляемого объекта. По моему опыту, это не всегда работает, но вы уже это сделали?

2. Здесь многое происходит, и переключение политик слияния не приведет к этому. Очевидно, что нужно исправить архитектурную проблему, но мне сложно ее диагностировать, не имея дополнительной информации о том, что происходит. И это та информация, которую я упускаю. Я установил NSQueryGeneration в свой основной контекст, и это прекратило исключения, но пользовательский интерфейс заметно отстает от данных.

Ответ №1:

При использовании NSPersistentContainer вычеркните все свои T:

  • Найдите ссылки на viewContext во всем вашем проекте. Убедитесь, что он вызывается только в основном потоке
  • Остерегайтесь расширений утилиты NSManagedObject. Благими намерениями вымощена дорога в ад. При расширении NSManagedObject всегда обращайтесь к self.managedObjectContext , если это необходимо.
  • В приложениях с интенсивным использованием потоков считывайте из mainContext, записывайте в фоновом контексте. Будьте терпеливы, не обновляйте / обновляйте / запрашивайте viewContext, чтобы получать больше обновлений в пользовательском интерфейсе. Не загрязняйте чтение.
  • Остерегайтесь вызовов ‘refreshFoo’ / ‘calculateBar’ при обратных вызовах NSFetchRequestController. Пусть данные поступают в пользовательский интерфейс вашего приложения. не тяните его.