Pergunta

Eu gostaria de salvar um objeto NSMutableDictionary em NSUserDefaults. O tipo de chave em NSMutableDictionary é NSString, o tipo de valor é NSArray, que contém uma lista de objecto que implementa NSCoding. Por documento, NSString e NSArray ambos estão em conformidade com NSCoding.

Estou recebendo este erro:

[NSUserDefaults setObject: forKey:]:. Tentativa de inserir o valor não-propriedade .... de classe NSCFDictionary

Foi útil?

Solução

eu descobri uma alternativa, antes excepto, que codificam o objecto da raiz (objeto NSArray) usando NSKeyedArchiver, que termina com NSData. Em seguida, use UserDefaults salvar o NSData.

Quando eu precisar os dados, eu li o NSData e uso NSKeyedUnarchiver para converter NSData volta para o objeto.

É um pouco complicado, porque eu preciso para converter de / para toda NSData, mas ele simplesmente funciona.

Aqui está um exemplo por solicitação:

Salvar:

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

Carga:

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

O elemento nos instrumentos de matriz

@interface CommentItem : NSObject<NSCoding> {
    NSString *value;
}

Em seguida, na implementação de CommentItem, fornece dois métodos:

-(void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:value forKey:@"Value"];
}

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

Qualquer um tem a melhor solução?

Obrigado a todos.

Outras dicas

Se você estiver salvando um objeto em padrões do usuário, todos os objetos, de forma recursiva, todo o caminho, tem de ser propriedade da lista de objetos. Em conformidade com NSCoding não significa nada NSUserDefaults aqui-- não codificá-los automaticamente em NSData, você tem que fazer isso mesmo. Se a sua "lista de objeto que implementa NSCoding", os objectos que não são lista de propriedades objetos, então você vai ter que fazer algo com eles antes de salvar a padrões do usuário.

FYI as classes de lista propriedade são NSDictionary, NSArray, NSString, NSDate, NSData e NSNumber. Você pode escrever subclasses mutáveis ??(como NSMutableDictionary) para as preferências do usuário, mas os objetos que você leu será sempre imutável.

Tem todas as suas chaves nas NSStrings dicionário? Eu acho que eles têm que estar em ordem para salvar o dicionário para uma lista de propriedades.

Simplest Resposta:

NSDictionary é apenas uma objeto plist , se os chaves são NSStrings . Então, guarde o "Key" como NSString com stringWithFormat.


Solução:

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

Benefícios:

  1. Ele irá adicionar String-Valor .
  2. Ele irá adicionar Vazio-Value quando o valor da variável é NULL.

Você já pensou em olhar para a implementação do Protocolo NSCoding? Isso permitirá que você codificar e decodificar no iPhone com dois métodos simples que são implementadas com o NSCoding. Primeiro você precisa adicionar o NSCoding à sua classe.

Aqui está um exemplo:

Este é no arquivo .h

@interface GameContent : NSObject <NSCoding>

Em seguida, você precisará implementar dois métodos do Protocolo 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"];
    }

Confira a documentação sobre NSCoder para mais informações. Que veio em muito útil para meus projetos onde eu preciso para salvar o estado do aplicativo no iPhone, se o aplicativo é fechado e restaurá-lo de volta ao seu estado quando a sua volta.

A chave é para adicionar o protocolo para a interface e, em seguida, implementar os dois métodos que fazem parte do NSCoding.

Espero que isso ajude!

Não há uma solução melhor. Outra opção seria apenas para salvar o objeto codificado no disco - mas que está fazendo a mesma coisa. Ambos acabam com NSData que será decodificado quando você o quer de volta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top