Почему NSUserDefaults не удалось сохранить NSMutableDictionary в iPhone SDK?

Я хотел бы сохранить объект NSUserDefaults в NSUserDefaults . Ключевым типом в NSMutableDictionary является NSString , тип значения – NSArray , который содержит список объектов, реализующих NSCoding . В NSArray документе NSString и NSArray соответствуют NSCoding .

Я получаю эту ошибку:

[NSUserDefaults setObject: forKey:]: Попытка вставить значение non-property …. classа NSCFDictionary.

Любое решение для этого?

Я обнаружил одну альтернативу, прежде чем сохранять, я кодирую корневой объект (объект NSArray ) с помощью NSKeyedArchiver , который заканчивается NSData . Затем используйте UserDefaults, чтобы сохранить NSData .

Когда мне нужны данные, я зачитываю NSData и использую NSKeyedUnarchiver для преобразования NSData обратно в объект.

Это немного громоздко, потому что мне нужно каждый раз конвертировать в / из NSData , но он просто работает.

Вот один пример для запроса:

Сохранить:

 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSMutableArray *arr = ... ; // set value NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr]; [defaults setObject:data forKey:@"theKey"]; [defaults synchronize]; 

Нагрузка:

 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSData *data = [defaults objectForKey:@"theKey"]; NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 

Элемент массива реализует

 @interface CommentItem : NSObject { NSString *value; } 

Затем в реализации CommentItem предусмотрены два метода:

 -(void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:value forKey:@"Value"]; } -(id)initWithCoder:(NSCoder *)decoder { self.value = [decoder decodeObjectForKey:@"Value"]; return self; } 

У кого-то есть лучшее решение?

Всем спасибо.

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

FYI classы classов NSDictionaryNSDictionary , NSArray , NSString , NSDate , NSData и NSNumber . Вы можете записывать изменяемые подclassы (например, NSMutableDictionary ) в пользовательские настройки, но объекты, которые вы зачитали, всегда будут неизменными.

Все ваши ключи в словаре NSString ? Я думаю, что они должны быть, чтобы сохранить словарь в списке свойств.

Простой ответ:

NSDictionary – это только объект NSDictionary , если ключи являются NSStrings . Итак, stringWithFormat «ключ» как NSString с помощью stringWithFormat .


Решение :

 NSString *key = [NSString stringWithFormat:@"%@",[dictionary valueForKey:@"Key"]]; 

Выгоды :

  1. Он добавит String-Value .
  2. Он добавит пустое значение, когда значение Value Variable равно NULL .

Рассматривали ли вы вопрос об NSCoding протокола NSCoding ? Это позволит вам кодировать и декодировать iPhone с помощью двух простых методов, которые реализуются с помощью NSCoding . Сначала вам нужно добавить NSCoding в свой class.

Вот пример:

Это файл .h

 @interface GameContent : NSObject  

Затем вам нужно будет реализовать два метода протокола NSCoding.

  - (id) initWithCoder: (NSCoder *)coder { if (self = [super init]) { [self setFoundHotSpots:[coder decodeObjectForKey:@"foundHotSpots"]]; } return self; } - (void) encodeWithCoder: (NSCoder *)coder { [coder encodeObject:foundHotSpots forKey:@"foundHotSpots"]; } 

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

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

Надеюсь, это поможет!

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

  • Метод Swizzle на устройстве iPhone
  • Как читать трассировки стека объектов-c
  • Как распечатать имя метода и номер строки и условно отключить NSLog?
  • как отобразить тестовый баннер IAd в симуляторе
  • Кто-нибудь реализовал API PayPal через собственное приложение для iPhone?
  • Создание пользовательского UIKeyBoard для iPhone
  • Как я могу получить точное время, например, в миллисекундах в Objective-C?
  • Почему UINavigationBar крадет события касания?
  • Предупреждать, когда не вызывается
  • Полужирный и нежирный текст в одном UILabel?
  • Возможно открытие всплывающих ссылок в UIWebView?
  • Давайте будем гением компьютера.