Я потратил большую часть рабочего дня, пытаясь решить эту проблему.
Фон
У меня простая базовая модель данных с книгами и сеансами чтения. В книгах есть обложки (изображения), которые хранятся в виде двоичных данных с помощью "Разрешить внешнее хранилище".
На iOS 11.4 и ниже все работает отлично все время. Когда я сохраняю новый сеанс, все обновляется должным образом.
проблема
Начиная с iOS 12, когда я создаю новый сеанс чтения и связываю его с книгой, каждый второй раз основные данные генерируют инструкцию SQL, которая также обновляет поле обложки книги, что иногда приводит к плохой ссылке (на файл на диске), которая часто приводит к тому, что обложка равна нулю при перезапуске приложения и почти всегда создает дубликат копии обложки на диске (как видно _EXTERNAL_DATA
папки Simulator _EXTERNAL_DATA
).
Контекст и объекты в памяти остаются правильными (и, следовательно, все в пользовательском интерфейсе), пока приложение не будет перезапущено, тогда обложка часто равна нулю.
Спецификация iOS 12
На iOS 12 я могу детерминистически воспроизвести ошибку в симуляторе, на физических устройствах, и пользователи также сообщили об ошибке. Я не могу воспроизвести ошибку на iOS 11.4, и ни одна из пользователей не сообщила об ошибке, предшествующей iOS 12.
Сделанные шаги
-
Я включил "
-com.apple.CoreData.ConcurrencyDebug 1
", поэтому не должно быть, что я получаю доступ к чему-либо из неправильной очереди. Я также включил "-com.apple.CoreData.SQLDebug 3
", чтобы я мог точно видеть, что написано. -
Я убедился, что экземпляр книги (и, следовательно, обложка) не изменен моим кодом перед ассоциацией с новым
newSession.book = book
проверивhasChanges
, как раз перед тем, как я сделаюnewSession.book = book
иcontext.save()
. -
Чтобы быть на 100% уверенным, что я не касаюсь свойства обложки ни на одном потоке, я коротко замыкал мои получатели и сеттеры для этого свойства. Без улучшения.
-
Я попытался использовать
objectID
для запроса экземпляра книги непосредственно перед ассоциацией и сохранения. Без улучшения. -
Я даже попробовал вариант, где контекст содержит сильные ссылки на все объекты, просто чтобы убедиться, что это не проблема управления памятью. Без улучшения.
Вопрос
Любые идеи для следующих шагов?
Обновление статуса
Это дефект в iOS 12. См. Принятый ответ ниже для подробного описания резонансного обходного пути.