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


153

Ao olhar para a documentação, quase não vejo grande diferença. Tanto "valor" quanto "objeto" são do tipo id , portanto, pode ser qualquer objeto. Key já foi uma string e, no outro caso, um id. Um deles parece reter o objeto e o outro não. O quê mais? Qual é para qual caso?


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?


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.


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”).


Obrigado por fornecer o motivo atual pelo qual setObject: forKey: gera uma exceção. @breakfreehg
simbesi.com
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.