#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. Пусть данные поступают в пользовательский интерфейс вашего приложения. не тяните его.