Итак, я взглянул на документацию Apple по методу NSUserDefaults synchronize (). См. Ниже для справки:

https://developer.apple.com/reference/foundation/userdefaults/1414005-synchronize

На странице сейчас написано:

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

Однако я до сих пор не понимаю, когда следует вызывать этот метод? Например, следует ли его вызывать каждый раз, когда пользователь меняет настройки приложения? Или я должен просто верить, что фоновый api справится с этим? И приводит ли закрытие представления сразу после изменения настроек в памяти к потере этого изменения?

Кроме того, когда сбой вызова synchronize () может привести к неправильному изменению пользовательских настроек?

Кроме того, какова стоимость (производительность, память или иначе) вызова этого метода? Я знаю, что это связано с чтением и записью с / на диск, но действительно ли это требует таких усилий на телефонах?

10
James Stonehill 25 Ноя 2016 в 18:20

4 ответа

Лучший ответ

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

Единственная причина, по которой существует метод synchronize, заключается в том, что ваше приложение может сказать NSUserDefaults сохранить словарь «сейчас» вместо того, чтобы ждать автоматического сохранения, которое в конечном итоге произойдет.

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

В моих собственных приложениях единственное место, где я вызываю synchronize, - это метод делегата applicationDidEnterBackground. Это необходимо для того, чтобы последние несохраненные изменения сохранялись на тот случай, если приложение будет закрыто в фоновом режиме.

Я думаю, что большая часть путаницы возникает из-за отладки приложения во время разработки. Нередко во время разработки вы завершаете работу приложения с помощью кнопки «стоп» в отладчике. И часто это происходит до того, как будут сохранены самые последние NSUserDefaults изменения. Поэтому я выработал привычку помещать свое приложение в фоновый режим, нажимая кнопку «Домой» перед тем, как убивать приложение в отладчике, когда я хочу убедиться, что последние обновления сохраняются.

Учитывая приведенное выше резюме, давайте рассмотрим ваши вопросы:

должен ли он вызываться каждый раз, когда пользователь меняет настройки приложения?

Нет. Как описано выше, любое изменение автоматически становится доступным немедленно.

Или я должен просто верить, что фоновый api справится с этим?

Да, доверяйте автоматическому постоянству, за исключением вызова synchronize, когда ваше приложение переходит в фоновый режим.

И приводит ли закрытие представления сразу после изменения настроек в памяти к потере этого изменения?

Это не имеет никакого эффекта. Как только вы добавляете / редактируете / удаляете ключ / значение в NSUserDefaults, изменения вносятся.

Кроме того, когда сбой вызова synchronize () может привести к неправильному изменению пользовательских настроек?

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

Кроме того, какова стоимость (производительность, память или иначе) вызова этого метода? Я знаю, что это связано с чтением и записью с / на диск, но действительно ли это требует таких усилий на телефонах?

Автоматическое сохранение выполняется в фоновом режиме и просто записывает словарь в файл plist. Это очень быстро, если вы не следуете рекомендациям. Это будет медленнее, если вы неправильно используете NSUserDefaults для хранения больших объемов данных.

31
Hamish 25 Ноя 2016 в 18:19

документация Apple для synchronize() была обновлена и теперь читается :

Ожидает любых ожидающих асинхронных обновлений в базе данных по умолчанию и возвращает; этот метод не нужен и его не следует использовать .

6
Andrew Bennet 7 Апр 2018 в 13:02

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

Проверьте документацию Apple: Официальная ссылка

0
Raj Aryan 24 Янв 2018 в 10:13

< Сильный > UPDATE

Как и ожидалось, он устарел , как упоминалось в Apple. Документ

синхронизировать ()

Ожидает любых ожидающих асинхронных обновлений в базе данных по умолчанию и возвращает; этот метод не нужен и не должен использоваться.

Оригинальный ответ

synchronize будет упразднен, как указано здесь

- синхронизация устарела и будет отмечена макросом NS_DEPRECATED в будущем выпуске.

-synchronize блокирует вызывающий поток до тех пор, пока не будут завершены все выполняемые операции набора. В этом больше нет необходимости. Замены для предыдущего использования -synchronize зависят от того, какова была цель вызова synchronize. Если вы синхронизировали…

-… перед чтением, чтобы получить обновленные значения: удалить вызов синхронизации

-… после записи, чтобы уведомить другую программу о необходимости чтения: другая программа может использовать KVO для соблюдения значения по умолчанию без необходимости уведомления -… перед выходом из процесса, не являющегося приложением (инструмент командной строки, агент или демон): вызовите CFPreferencesAppSynchronize (kCFPreferencesCurrentApplication)

-… по любой другой причине: удалить вызов синхронизации

3
sasquatch 20 Ноя 2018 в 10:21