156

When looking at the documentation, I hardly see any big difference. Both "value" and "object" are of type id, so can be any object. Key is once a string, and in the other case an id. One of them seems to retain the object, and the other don't. What else? Which one is for what case?

Bhavin Bhadani
  • 22,224
  • 10
  • 78
  • 108
  • possible duplicate of [Objective-C: What's the Difference between objectForKey and valueForKey?](http://stackoverflow.com/questions/1062183/objective-c-whats-the-difference-between-objectforkey-and-valueforkey) – mmmmmm Jun 22 '12 at 10:59

4 Answers4

167

setValue:forKey: is part of the NSKeyValueCoding protocol, which among other things, lets you access object properties from the likes of Interface Builder. setValue:forKey: is implemented in classes other than NSDictionary.

setObject:forKey: is NSMutableDictionary's reason to exist. Its signature happens to be quite similar to setValue:forKey:, but is more generic (e.g. any key type). It's somewhat of a coincidence that the signatures are so similar.

What adds to the confusion is that NSMutableDictionary's implementation of setValue:forKey: is equivalent to setObject:forKey: in most cases. In other classes, setValue:forKey: changes member variables. In NSMutableDictionary, it changes dictionary entries, unless you prefix the key with a '@' character -- in which case it modifies member variables.

So, in a nutshell, use setObject:forKey: when you need to work with dictionary keys and values, and setValue:forKey: in the rarer cases where you need to tackle KVP.

EDIT: and oh, it looks like this has been asked and answered before: Difference between objectForKey and valueForKey?

Community
  • 1
  • 1
Oren Trutner
  • 23,752
  • 8
  • 54
  • 55
  • that question is not exactly the same. it is about the getter methods, whereas this question is about the setter methods – user102008 Feb 16 '11 at 02:22
  • 1
    What do you mean by "In NSMutableDictionary, it changes dictionary entries, unless you prefix the key with a '@' character -- in which case it modifies member variables." What member variables? Also maybe you can comment on http://stackoverflow.com/questions/5755917/ ? Thanks. – Peter Štibraný Apr 22 '11 at 14:08
  • just for completeness, setObject:forKey will raise (exception) if object is nil. Will setValue:forKey behave the same, or will it remove existing object from dictionary when setting nil for key? – Motti Shneor May 02 '16 at 10:58
  • Great answer. Really. for completeness though, it would be nice to mention that (on NSMutableDictionary at least) setValue:forKey: tolerates nil values, and removes the entry - while setObject:forKey: will throw exception and crash when handed nil values. – Motti Shneor Feb 12 '19 at 06:24
  • In general, I recommend to use the modern Objective-C Syntax with `NSMutableDictionary` which completely avoids the confusion: ` NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init]; myDict[myKey] = myValue; ` – tomacco Sep 01 '20 at 11:07
85

Another difference is that if you give a nil value to setValue:forKey:, it removes the key from the dictionary if it exists, otherwise does nothing. But if you give a nil value to setObject:forKey:, it raises an exception.

user102008
  • 30,736
  • 10
  • 83
  • 104
  • 11
    This is super useful to know. I had otherwise written my own category on NSMutableDictionary to accomplish exactly this!. Thanks – Arman Nov 12 '12 at 20:13
  • 2
    Another difference is with objective-c subscripting, you can write `dic[key] = value;` to support removing the key if value is `nil`. Subscripting is generally a better approach than `setValue:forKey:` to accomplish this. – Cœur Mar 08 '16 at 11:33
11

-setValue:forKey: just send -setObject:forKey: to the receiver, unless the value is nil, in which case send -removeObjectForKey.

Dead simple.

Jakub Truhlář
  • 20,070
  • 9
  • 74
  • 84
  • oh you're right, bro. Sorry about that. It's documented here: https://developer.apple.com/reference/foundation/nsmutabledictionary/1416335-setvalue?language=objc – Eddie Oct 19 '16 at 10:29
4

anObject — The value for key. The object receives a retain message before being added to the NSDictionary. This value must not be nil.

aKey — The key for value. The key is copied (using copyWithZone:; keys must conform to the NSCopying protocol). The key must not be nil.

value — The value for key.

key — The key for value. Note that when using key-value coding, the key must be a string (see “Key-Value Coding Fundamentals”).

Atulkumar V. Jain
  • 5,102
  • 9
  • 44
  • 61
breakfreehg
  • 618
  • 1
  • 6
  • 16