Подтвердить что ты не робот

Когда (не) злоупотреблять NSUserDefaults

Интересно, для чего нужны рекомендации:
1 - как часто я могу читать из NSUserDefaults
2 - сколько данных я могу разумно хранить в NSUserDefaults

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

Некоторые примеры среди других:

  • Если в моей игре есть опция для того, чтобы компьютер был одним из игроков, я буду использовать NSUserDefaults, чтобы сохранить это логическое значение. Это ясно. Но также разумно ли обращаться к NSUserDefaults во время моей игры каждый раз, когда я хочу знать, является ли компьютер игроком или я должен использовать вместо него переменную экземпляра? Предположим, что мне нужно проверять, что булевая каждую секунду. Является ли ответ тем же самым 100 мс вместо этого? Как насчет каждые 10 с?

  • Если в моей игре 50 движущихся объектов, и я хочу, чтобы их позиции и скорости сохранялись, когда пользователь закрывает приложение, NSUserDefaults является разумным местом для хранения этих данных? Что относительно 20 движущихся объектов? Что насчет 200?

4b9b3361

Ответ 1

Не беспокойтесь о лимитах. Вместо этого задайте себе этот простой вопрос:

Это предпочтение?

Если это предпочтение, то оно должно быть в настройках по умолчанию. Для чего предназначены пользователи по умолчанию. Если нет, то он должен находиться в каталоге Documents (или, на Mac, возможно, в поддержке приложений).

В iOS вы можете указать, будет ли это предпочтение или нет, было бы целесообразно (если возможно) поместить его в свой набор настроек для отображения и редактирования в приложении "Настройки". В Mac OS X вы обычно можете указать, будет ли это предпочтение или нет, было бы целесообразно поместить его в окно настроек.

Конечно, это зависит от вашего суждения. Например, Stanza для Mac, ошибочно, ставит не-предпочтения в окне настроек.

Вы также можете рассмотреть вопрос по его обращению:

Являются ли эти созданные пользователем данные?

Предпочтение, по которому вы будете иметь значение по умолчанию, - это не созданные пользователем данные; это данные, переопределенные пользователем. Не менее плохо, чтобы потерять его, но он сообщает, где вы должны его хранить.

Ответ 2

Интересно, для чего нужны руководящие принципы: 1 - как часто я могу читать из NSUserDefaults

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

2 - сколько данных я могу разумно хранить в NSUserDefaults

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

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

просто добавьте const bool к объекту противника. нулевая потеря времени выполнения, кроме памяти, которая не будет существенной.

Предположим, что мне нужно проверить, что булевая каждую секунду. Является ли ответ тем же самым 100 мс вместо этого? Как насчет каждые 10 с?

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

Если в моей игре 50 движущихся объектов, и я хочу, чтобы их позиции и скорости были сохранены, когда пользователь покидает приложение, NSUserDefaults является разумным местом для хранения этих данных? Что относительно 20 движущихся объектов? Что насчет 200?

все будет хорошо, хотя я не буду читать/писать через пользовательские настройки во время игры; просто сохраните/загрузите состояние по мере необходимости.

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

Ответ 3

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

Тем не менее, NSUserDefaults использует кеш в памяти, и стоимость возникает только при синхронизации. Согласно документации синхронизация происходит "автоматически... с периодическими интервалами"; Я считаю, что это применимо только в том случае, если что-то изменилось.

Итак, для проверки того, является ли компьютер игроком, используйте NSUserDefaults после того, как кадр не будет проблемой с момента его кэширования. Для хранения состояния игры это может быть проблемой производительности, если вы постоянно ее обновляете, и, как говорит Питер Хоуси, это семантическое злоупотребление.

Ответ 4

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

Ответ 5

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

Я бы использовал разные технологии для различной информации/данных.

  • Маленькие биты данных с серверов, предпочтения, информация пользователя и т.д. Я бы использовал NSUserDefaults.

  • Для информации для входа (токены доступа, конфиденциальные данные), я бы использовал цепочку ключей. Брелок для ключей можно также использовать для данных, которые не должны удаляться при удалении приложения.

  • Для больших объемов данных сервера или игровых данных я бы записал его на диск, но сохранил его в памяти.

В вашей ситуации я бы сохранил его в памяти (возможно, @property), но я бы периодически записывал его на диск (возможно, каждый раз от одного до пяти раз он менялся, использовал int ivar). Убедитесь, что этот метод записи на диске находится в AppDelegate, так что он не сбой при закрытии контроллера представления, который его выполняет.

Таким образом, данные легко доступны, но также сохраняются на диске для безопасного хранения.