IOS 10 с XCode 8 GM заставил NSUserDefaults прерывисто работать
ПРИМЕЧАНИЕ: Я видел много других сообщений о переполнении стека о NSUserDefaults
, которые были переименованы в UserDefaults
в Swift или не работают на симуляторе до перезапуска. В любом случае это не дубликат. Многие вопросы, на которые ссылаются теги, - это 4 года назад. Мой вопрос специфичен для iOS 10 с этого года, поскольку он всегда работал в более старых версиях. Я уже упоминал в своем вопросе, что мой вопрос не является дубликатом этих вопросов, так как это были ошибки симулятора в swift, и моя проблема связана с ошибкой объекта C. Пожалуйста, прочитайте вопросы перед тем, как пометить их как дубликаты
Моя проблема отличается, поскольку я могу воспроизвести это на объективе C и на самом физическом устройстве.
Я создал совершенно новый проект с нуля для этого теста. Я разместил этот код в viewDidLoad
контроллера вида:
if (![[NSUserDefaults standardUserDefaults] valueForKey:@"checkIfInitialized"]){
NSLog(@"setting checkIfInitialized as not exist");
[[NSUserDefaults standardUserDefaults] setValue:@"test" forKey:@"checkIfInitialized"];
[[NSUserDefaults standardUserDefaults] synchronize];
self.view.backgroundColor=[UIColor redColor];
[email protected]"NSUserDefaults was NOT there, try running again";
} else {
NSLog(@"checkIfInitialized exists already");
self.view.backgroundColor=[UIColor blueColor];
[email protected]"NSUserDefaults was already there this time, try running again";
}
Теперь, если я запустил приложение примерно 10 раз, несколько раз он находит checkIfInitialized
, а иногда нет. Нет точного числа, сколько раз он терпит неудачу, так как он может работать 3 раза, а затем проваливаться через 2 раза, затем работать 4 раза и терпеть неудачу один раз и т.д.
Теперь что-то, что я заметил (не уверенно на 100%), что проблема возникает, только когда я тестирую подключение через Xcode. Если я запустил приложение, щелкнув значок приложения на устройстве без Xcode, тогда он работает нормально, но я не могу быть на 100% уверенным.
Я заметил, что эта ошибка возникает иногда:
[User Defaults] Failed to write value for key checkIfInitialized in CFPrefsPlistSource<0x1700f7200> (Domain: com.xxxx.appname, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null)): Path not accessible, switching to read-only
У меня есть этот очень простой проект на моем Dropbox, если вы хотите проверить его.
Я бы предложил тестирование примерно 10-15 раз, чтобы воспроизвести эту проблему.
https://www.dropbox.com/s/j7vbgl6e15s57ix/nsuserdefaultbug.zip?dl=0
Это отлично работает на iOS 9, что определенно связано с iOS 10.
ИЗМЕНИТЬ
Ошибка: 28287988
Ответ от команды Apple DTS:
Прежде всего, вы должны сначала определить, являются ли стандартнымиUserDefaults или ЗначениеForKey не работает. Я предполагаю, что "standardUserDefaults" возвращая NULL, и если это так, то это то, что вы должны быть защищены от общего. Примечательно, что standardUserDefaults вернет NULL, если файл предпочтения зашифрован в среда, в которой в настоящее время работает приложение (например, предпочтения установлено значение "NSFileProtectionComplete", и приложение запускается в задний план). Это не должно быть проблемой для стандартного переднего плана приложений, но это то, что нужно знать в любом случае.
Скорее всего, Xcode фактически вызывает проблему здесь. Xcode значительно усложняет среду запуска приложения таким образом, что ОЧЕНЬ отличается от стандартного запуска приложения. Я предполагаю, что это в основном, инициируется синхронизацией Xcodes, вызывая ожидаемый ситуации во время запуска приложения, но если вы хотите более формальный тест которые пытаются установить единую точку останова в applicationDidFinishLaunching и продолжать в отладчике, как только вы его ударили. Мое предположение просто добавляя, что нарушает время, достаточное, чтобы остановить проблему из происходит. Вроде. Его iOS 10 только в том смысле, что iOS 9 никогда не печатайте это сообщение журнала, но это потому, что сообщение журнала было добавлен в iOS 10. Сам код достаточно похож на iOS 9.3, что я подозревают, что такое же поведение (по крайней мере теоретически) возможно в iOS 9.
Ответы
Ответ 1
Да, это определенно воспроизводимая ошибка.
- Это происходит с выпуском GM Xcode 8 и iOS 10.
- не связанный вопрос со ссылкой на Swift.
- Это не связанный вопрос, относящийся к бета-версиям симулятора.
Ошибка происходит на устройствах и на симуляторе. Это прерывисто: сохранение будет работать шесть раз, а затем сбой. В отличие от вас, я не получил сообщение "не удалось написать ключ".
Ошибка также возникает при работе непосредственно на устройстве без Xcode. Это на самом деле то, как я его обнаружил.
Вы должны сообщить об ошибке в Apple, тем более, что у вас есть короткая программа, которая будет воспроизводить ее. Я сделаю то же самое.
Одно ключевое различие: В моем случае ошибка записывается по умолчанию. Ранее записанное значение остается в NSUserDefaults. Иногда один ключ успешно записывается, а другой не изменяется.
Ответ 2
Аналогично очень интеллектуальный ответ DTS из моего собственного запроса поддержки. В принципе, убийство с использованием Xcode более убийственно, чем что-либо, что, естественно, произойдет на устройстве (даже метод с двойным нажатием кнопки "вверх" и "вверх-вниз" ), и поскольку все внезапно разбивается, когда Xcode останавливает его, ленивая запись NSUserDefaults может завершиться неудачей, или быть только наполовину завершенным.
И действительно, чистое тестирование устройства на устройстве без участия Xcode показывает, что все правильно записывается в NSUserDefaults, когда приложение завершается.
Я закрыл свой собственный отчет об ошибке.