установить значение в UserDefaults синхронно

Я пытаюсь сохранить логическое значение в UserDefault в быстром режиме. поэтому, когда я устанавливаю значение в userDefault, моя следующая инструкция — переключиться на контроллер представления и закрыть текущий контроллер представления.

Итак, что происходит сейчас, иногда userDefault сохраняет значение в БД, а иногда нет. Я читаю документацию Apple https://developer.apple.com/documentation/foundation/userdefaults и обнаружил, что

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

так, я предполагаю, потому что в самой следующей строке я открываю новый контроллер и закрываю текущий, из-за чего возникает несогласованность.

вот мой код

func setWalkthroughShown(completionHandler: @escaping ()->()) {
        UserDefaults.standard.set(true, forKey: isWalkthroughCompleted)
        UserDefaults.standard.synchronize()
        completionHandler()
    }

Я даже вызвал UserDefaults.standard.synchronize(), чтобы операция стала синхронной. хотя в документации явно написано не использовать эту функцию. может кто-нибудь, пожалуйста, направьте меня, где я ошибаюсь? как я могу сохранить во всех местах перед закрытием текущего процесса?

это функция, с помощью которой я получаю значение

func isWalkthroughShown() -> Bool {
        return UserDefaults.standard.bool(forKey: isWalkthroughCompleted)
    }

здесь isWalkthroughCompleted - это строка, и вы можете видеть, что я использую одну и ту же строку для сохранения и извлечения значения.


person Ahsan    schedule 27.01.2021    source источник
comment
Что вы имеете в виду под закрытием текущего процесса? Вы убиваете приложение? Переключение между контроллерами представления не должно иметь ничего общего с UserDefaults. Любая запись в UserDefaults должна быть немедленно видна любым последующим чтением в UserDefaults в том же процессе (т. е. без уничтожения приложения). Сначала я подозреваю, что ваш вызов .set на самом деле не работает во всех случаях. Я бы проверил, что это с точками останова или операторами регистрации.   -  person Rob Napier    schedule 28.01.2021
comment
Помните, что смысл сообщения, которое вы написали здесь, заключается в том, что UserDefaults кэшируется в памяти. Он не перезагружает базу данных с диска каждый раз, когда вы читаете, поэтому даже если он еще не записал значения на диск, это не имеет значения в рамках одного и того же процесса.   -  person Rob Napier    schedule 28.01.2021
comment
Спасибо. позвольте мне отлаживать снова.   -  person Ahsan    schedule 28.01.2021
comment
Вы показали две функции, но не показали ни одного кода, который вызывает ни одну из них. Покажите нам этот код, пожалуйста. В противном случае мы понятия не имеем, как вы все это тестируете (за исключением того, что вы тестируете явно неправильно). Например, возможно, ваши звонки совершаются в неправильном порядке. Но у нас нет возможности узнать, пока вы нам не покажете.   -  person matt    schedule 28.01.2021
comment
на самом деле, я пытался изменить корневой контроллер представления окна после переключения с этого контроллера представления на желаемый контроллер представления. вот почему я думал, что мой предыдущий контроллер представления не будет иметь ссылки в памяти, поэтому он может быть очищен сборщиком мусора, поэтому я говорю, что, возможно, на него повлияет изменение процесса. пожалуйста, поправьте меня, если я ошибаюсь. Благодарность   -  person Ahsan    schedule 28.01.2021
comment
Во-первых, нет сборщика мусора; есть ARC, который сильно отличается (в частности, он детерминирован в отличие от GC, но также он не обрабатывает циклы, которые обычно делают GC). Описываемая вами ситуация может освободить контроллер представления, а может и нет (вы можете узнать, поставив точку останова или оператор журнала в deinit). Я бы начал с доказательства того, что вызывается setWalkthroughShown, а затем доказывал, что после этого вызывается isWalkthroughShown и получает неправильное значение. (И что ничто другое никогда не устанавливает это значение!)   -  person Rob Napier    schedule 28.01.2021
comment
Я не знаю, что означает изменение контроллера корневого представления, и вы до сих пор не показали никакого соответствующего кода. Вы действительно хотели помочь?   -  person matt    schedule 28.01.2021
comment
@matt Я работал над клиентским проектом, поэтому он не разрешит мне делиться кодом. поэтому я попытаюсь сделать аналогичный сценарий и показать вам код. более того, эта проблема возникает, когда я перекомпилирую проект (в некоторых случаях, например, 1 из 4 раз, и если я не перекомпилирую, я еще не видел никакой ошибки). и определенно, братан, я получаю доступ к значению после сохранения. Я отладил его в деталях. в настоящее время у меня нет реального устройства. возможно, в реальном устройстве ошибки не возникают. Спасибо за вашу помощь.   -  person Ahsan    schedule 28.01.2021
comment
«Эта проблема возникает, когда я перекомпилирую проект» О. Так что просто подождите 20 секунд между остановкой и повторным запуском.   -  person matt    schedule 28.01.2021
comment
@matt, если я подожду более 10-20 секунд, а затем перекомпилирую, ошибка не появится. тем не менее, я организую физическое устройство и протестирую его.   -  person Ahsan    schedule 28.01.2021
comment
Вероятный дубликат stackoverflow.com/questions/52447225 /   -  person matt    schedule 28.01.2021
comment
@мат, это сработало. Благодарность   -  person Ahsan    schedule 01.02.2021


Ответы (1)


На самом деле, синтаксической ошибки при кодировании не было.

На самом деле я тестировал его неправильно. после отправки запроса на сохранение данных в пользовательских значениях по умолчанию я немедленно перекомпилировал, и поскольку значение сохраняется асинхронно, поэтому иногда из-за уничтожения процесса у меня возникала эта проблема. благодаря @matt. для получения подробной информации значения пользователей iOS по умолчанию отстают от сохраненного содержимого

person Ahsan    schedule 01.02.2021