it-roy-ru.com

Есть ли ограничения в хранении значений в NSUserDefaults?

Я новичок в разработке для iPhone и Objective C. Я использовал NSUserDefaults для хранения некоторых значений в моем приложении . Но я не знаю, есть ли ограничение для хранения значений в NSUserDefaults. Может кто-нибудь Помоги мне узнать это.

Заранее спасибо.

59
Johnykutty

Пока на iPhone/iPad достаточно места, вы можете хранить значения NSUserDefault. Все эти значения хранятся в файле .plist, и этот файл очень мал, большую часть времени занимает менее 1 КБ (если вы не храните много данных).

46
user914372

Существуют ограничения на типы, которые вы можете хранить: все они должны быть объектами списка свойств, а именно NSString, NSNumber, NSData, NSArray и NSDictionary. Кроме того, вы можете хранить только NSArray и NSDictionary, если значения также являются объектами списка свойств; также все ключи NSDictionary должны быть строками.

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

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

42
benzado

Все ответили на прямой вопрос "есть ли предел?" Тем не менее, я обнаружил, что этот поток действительно хочет понять "сколько слишком много для хранения в UserDefaults?"

Если вы ищете этот ответ, вот полезная тема . Ответы, которые я нашел полезными, должны были пойти в файл вашего проекта и посмотреть на размер файла plist:

5 предметов это почти ничто. Вам будет хорошо!


На моей машине у меня около 28 мегабайт данных по умолчанию. Это не вызывает никаких проблем.


Исходя из общего опыта программирования с массивами, я предполагаю, что производительность начинает быстро падать, когда вы переходите на 1000, в зависимости от размера элемента. Поэтому в программе у меня не будет проблемы с хранением пары сотен элементов. Это сказало, что я, вероятно, начну использовать базу данных sqlite3 или coredata, скорее, чем позже, если бы я был вами.

Важно помнить:

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

Однако, как указывали другие ответы, файл будет прочитан и записан целиком. Поэтому чтение 20 ключевых/строковых словарей и 5 ключевых/логических словарей просто для получения одной строки ... не совсем идеально. Тем не менее, если это не снижает производительность и экономит массу кода, почему бы и нет?

8
Dave G

Для хранения значений в NSUserDefaults нет ограничений.

4
Manmay

Единственное ограничение хранилища в NSUserDefaults - это емкость хранилища устройства

Если в iOSDevice имеется доступное пространство для хранения, вы практически можете хранить данные в NSUserDefaults. Пара ключ-значение хранится в структурированном XML-файле (.plist), который хранится в App Bundle.

По умолчанию система пользователя и хранилище значений ключей предназначены для хранение простых типов данных —строки, числа, даты, логические значения, URL s, объекты data и т. д. - в список свойств. Использование список свойств также означает, что вы можете организовать ваши данные предпочтений, используя типы массивов и словарей. Также возможно хранить другие объекты в списке свойств, сначала кодируя их в объект NSData.

4
Adromil Balais

Из iOS SDK коды и связанный с ним официальный документ Apple. .

extension UserDefaults {


    /*!
     NSUserDefaultsSizeLimitExceededNotification is posted on the main queue when more data is stored in user defaults than is allowed. Currently there is no limit for local user defaults except on tvOS, where a warning notification will be posted at 512kB, and the process terminated at 1MB. For ubiquitous defaults, the limit depends on the logged in iCloud user.
     */
    @available(iOS 9.3, *)
    public class let sizeLimitExceededNotification: NSNotification.Name


    // ....
 }   


Резюме

  1. В настоящее время нет ограничений по умолчанию для локальных пользователей. 
  2. На tvOS, где предупреждающее уведомление будет размещено на 512 КБ, а процесс завершен на 1 МБ.
  3. Для вездесущих значений по умолчанию ограничение зависит от пользователя, вошедшего в систему iCloud.
3
AechoLiu

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

Реальный вопрос должен заключаться в том, КАК ЧАСТО вы пишете новые/измененные значения ... И это связано с разрядкой батареи, которая вызывает эти записи.

У IOS нет шансов избежать физической записи на «диск» при изменении одного значения, просто чтобы сохранить целостность данных. Относительно UserDefaults это приводит к тому, что весь файл перезаписывается на диск. 

Это включает «диск» и поддерживает его в течение более длительного времени и предотвращает переход IOS в состояние низкого энергопотребления.

Из «Руководства по энергоэффективности для приложений iOS»:

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

ЧТЕНИЯ не являются проблемой, так как все значения кэшируются в памяти.

2
Hardy_Germany

Насколько мне известно, нет ограничений для хранения в NSUserdefaults.

2
Tendulkar

Какой бы максимальный размер файла не находился на диске. Вы можете использовать этот кусок кода, чтобы проверить это!

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *myKey = @"key";
int sizeOfFile = 1024; // Fill in proper file size here
NSData myObject;
NSString *someFilePath = @"PathToYourFileHere";

for(int i = 1; i < 9999999999999999; i++)
{
  myObject = [NSData dataWithContentsOfFile:someFilePath];
  [defaults setObject:myObject forKey:[NSString stringWithFormat:@"%@%i", myKey, i]];
  NSLog(@"Iteration: %i, TotalWritten: %i", i, i * sizeOfFile);
}
0
Esqarrouth