Onde está a diferença entre setObject: forKey: e setValue: forKey: no NSMutableDictionary?

Respostas:

163

setValue:forKey:faz parte do protocolo NSKeyValueCoding , que, entre outras coisas, permite acessar propriedades de objetos como o Interface Builder. setValue:forKey:é implementado em outras classes que não NSDictionary.

setObject:forKey:é uma NSMutableDictionary'srazão para existir. Sua assinatura é bem parecida com setValue: forKey :, mas é mais genérica (por exemplo, qualquer tipo de chave). É uma coincidência que as assinaturas sejam tão semelhantes.

O que aumenta a confusão é que a implementação de NSMutableDictionary setValue:forKey:é equivalente setObject:forKey:na maioria dos casos. Em outras classes,setValue:forKey: altera as variáveis ​​de membro. Em NSMutableDictionary, ele altera as entradas do dicionário, a menos que você prefixe a chave com um caractere '@' - nesse caso, modifica as variáveis ​​de membro.

Então, em poucas palavras, use setObject:forKey:quando precisar trabalhar com chaves e valores do dicionário e, setValue:forKey:nos casos mais raros, em que você precisará enfrentar o KVP .

EDIT: e oh, parece que isso foi perguntado e respondido antes: Diferença entre objectForKey e valueForKey?

Oren Trutner
fonte
essa pergunta não é exatamente a mesma. trata-se dos métodos getter, enquanto que esta pergunta é sobre os métodos setter
user102008
1
O que você quer dizer com "No NSMutableDictionary, ele altera as entradas do dicionário, a menos que você prefixe a chave com um caractere '@' - nesse caso, modifica as variáveis ​​de membro". Quais variáveis ​​de membro? Talvez você também possa comentar em stackoverflow.com/questions/5755917 ? Obrigado.
Peter Štibraný
apenas para completar, setObject: forKey aumentará (exceção) se o objeto for nulo. O setValue: forKey se comportará da mesma forma ou removerá o objeto existente do dicionário ao definir nulo para a chave?
Motti Shneor 02/05
Ótima resposta. Realmente. para completar, seria bom mencionar que (pelo menos no NSMutableDictionary) setValue: forKey: tolera valores nulos e remove a entrada - enquanto setObject: forKey: lança exceção e trava quando entregues valores nulos.
Motti Shneor 12/02/19
83

Outra diferença é que, se você atribuir um valor nulo setValue:forKey:, ele removerá a chave do dicionário, se existir, caso contrário, não fará nada. Mas se você atribuir um valor nulo setObject:forKey:, isso gera uma exceção.

user102008
fonte
10
Isso é super útil saber. Caso contrário, eu havia escrito minha própria categoria no NSMutableDictionary para fazer exatamente isso !. Graças
Arman
2
Outra diferença é com a assinatura do objetivo-c, você pode escrever dic[key] = value;para apoiar a remoção da chave, se o valor for nil. A assinatura é geralmente uma abordagem melhor do setValue:forKey:que fazer isso.
Cœur
4

anObject - O valor da chave. O objeto recebe uma mensagem de retenção antes de ser adicionado aoNSDictionary . Este valor não deve ser nulo.

aKey - A chave para o valor. A chave é copiada (usando copyWithZone:; as teclas devem estar em conformidade com o NSCopyingprotocolo). A chave não deve ser nula.

valor - o valor da chave.

chave - a chave para o valor. Observe que, ao usar a codificação de valor-chave, a chave deve ser uma string (consulte “Fundamentos da codificação de valor-chave”).

breakfreehg
fonte
Obrigado por fornecer o motivo atual pelo qual setObject: forKey: gera uma exceção. @breakfreehg
simbesi.com