Вопрос

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

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

[NSUserDefaults setObject:forKey:]:Попытка вставить несвойственное значение....класса 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<NSCoding> {
    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 & Quot; означает объекты, которые не являются объектами списка свойств, тогда вам придется что-то с ними делать, прежде чем сохранять их по умолчанию.

К вашему сведению, классами списка свойств являются NSDictionary, NSArray, NSString, NSDate, NSNumber и NSMutableDictionary. Вы можете записывать изменяемые подклассы (например, <=>) в пользовательские настройки, но считываемые объекты всегда будут неизменными.

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

Самый простой ответ.

NSDictionary является только списочным объектом , если ключи являются NSStrings . Поэтому сохраните & Quot; Key & Quot; как NSString с помощью stringWithFormat.

<Ч>

Решение:

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

Преимущества:

<Ол>
  • Это добавит String-Value .
  • Он добавит пустое значение , если значение переменной равно NULL.
  • Рассматривали ли вы вопрос реализации протокола NSCoding? Это позволит вам кодировать и декодировать на iPhone двумя простыми способами, которые реализованы с помощью <=>. Сначала вам нужно добавить <=> в ваш класс.

    Вот пример:

    Это в .h файле

    @interface GameContent : NSObject <NSCoding>
    

    Тогда вам нужно будет реализовать два метода протокола 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, если приложение закрыто, и вернуть его в состояние, когда оно снова включено.

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

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

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top