Où est la différence entre setObject: forKey: et setValue: forKey: dans NSMutableDictionary?

153

En regardant la documentation, je ne vois guère de grande différence. Les deux "valeur" et "objet" sont de type id , donc peut être n'importe quel objet. La clé est une fois une chaîne et dans l'autre cas un identifiant. L'un d'eux semble conserver l'objet, et l'autre non. Quoi d'autre? Lequel est pour quel cas?

Capitaine EI v2.0
la source

Réponses:

163

setValue:forKey:fait partie du protocole NSKeyValueCoding , qui, entre autres, vous permet d'accéder aux propriétés des objets à partir d'Interface Builder. setValue:forKey:est implémenté dans des classes autres que NSDictionary.

setObject:forKey:est une NSMutableDictionary'sraison d'exister. Sa signature se trouve être assez similaire à setValue: forKey :, mais est plus générique (par exemple tout type de clé). C'est un peu une coïncidence si les signatures sont si similaires.

Ce qui ajoute à la confusion, c'est que l'implémentation de NSMutableDictionary setValue:forKey:est équivalente setObject:forKey:dans la plupart des cas. Dans d'autres classes, setValue:forKey:change les variables de membre. Dans NSMutableDictionary, il modifie les entrées du dictionnaire, sauf si vous préfixez la clé avec un caractère «@» - auquel cas il modifie les variables membres.

Donc, en un mot, à utiliser setObject:forKey:lorsque vous avez besoin de travailler avec des clés et des valeurs de dictionnaire, et setValue:forKey:dans les cas plus rares où vous devez vous attaquer à KVP .

EDIT: et oh, il semble que cela a déjà été demandé et répondu: Différence entre objectForKey et valueForKey?

Oren Trutner
la source
cette question n'est pas exactement la même. il s'agit des méthodes getter, alors que cette question concerne les méthodes setter
user102008
1
Qu'entendez-vous par "Dans NSMutableDictionary, il modifie les entrées du dictionnaire, sauf si vous préfixez la clé avec un caractère '@' - auquel cas il modifie les variables membres." Quelles variables membres? Peut-être pouvez-vous également commenter sur stackoverflow.com/questions/5755917 ? Merci.
Peter Štibraný
juste pour être complet, setObject: forKey lèvera (exception) si object est nul. SetValue: forKey se comportera-t-il de la même manière ou supprimera-t-il l'objet existant du dictionnaire lors de la définition de nil pour la clé?
Motti Shneor
Très bonne réponse. Vraiment. pour être complet cependant, il serait bien de mentionner que (sur NSMutableDictionary au moins) setValue: forKey: tolère les valeurs nulles et supprime l'entrée - tandis que setObject: forKey: lancera une exception et plantera quand on lui remettra des valeurs nulles.
Motti Shneor
83

Une autre différence est que si vous donnez une valeur nulle à setValue:forKey:, il supprime la clé du dictionnaire si elle existe, sinon ne fait rien. Mais si vous donnez une valeur nulle à setObject:forKey:, cela lève une exception.

user102008
la source
10
C'est super utile à savoir. J'avais autrement écrit ma propre catégorie sur NSMutableDictionary pour accomplir exactement cela !. Merci
Arman
2
Une autre différence est avec l'indication objective-c, vous pouvez écrire dic[key] = value;pour prendre en charge la suppression de la clé si la valeur est nil. La souscription est généralement une meilleure approche que setValue:forKey:pour y parvenir.
Cœur
4

anObject - La valeur de la clé. L'objet reçoit un message de conservation avant d'être ajouté au NSDictionary. Cette valeur ne doit pas être nulle.

aKey - La clé de la valeur. La clé est copiée (en utilisant copyWithZone:; les clés doivent être conformes au NSCopyingprotocole). La clé ne doit pas être nulle.

value - La valeur de la clé.

key - La clé de valeur. Notez que lorsque vous utilisez le codage clé-valeur, la clé doit être une chaîne (voir «Principes de base du codage clé-valeur»).

petit-déjeuner
la source
Merci d'avoir donné la raison pour laquelle setObject: forKey: déclenche une exception. @breakfastreehg
simbesi.com