Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C: What is the difference between forKey and forKeyPath?

What is the difference between forKey and forKeyPath in NSMutableDicitionary's setValue method? I looked both up in the documentation and they seemed the same to me. I tried following code, but I couldn't distinguish the difference.

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:@"abc" forKey:@"ABC"];
[dict setValue:@"123" forKeyPath:@"xyz"];
for (NSString* key in dict) {
    id val = [dict objectForKey:key];
    NSLog(@"%@, %@", key, val);
}
like image 345
Takayuki Sato Avatar asked Jul 11 '12 13:07

Takayuki Sato


2 Answers

Both methods are part of Key-Value Coding and should not generally be used for element access in dictionaries. They only work on keys of type NSString and require specific syntax.

The difference between both of them is that specifying a (single) key would just look up that item.

Specifying a key path on the other hand follows the path through the objects. If you had a dictionary of dictionaries you could look up an element in the second level by using a key path like "key1.key2".

If you just want to access elements in a dictionary you should use objectForKey: and setObject:forKey:.

Edit to answer why valueForKey: should not be used:

  1. valueForKey: works only for string keys. Dictionaries can use other objects for keys.
  2. valueForKey: Handles keys that start with an "@" character differently. You cannot access elements whose keys start with @.
  3. Most importantly: By using valueForKey: you are saying: "I'm using KVC". There should be a reason for doing this. When using objectForKey: you are just accessing elements in a dictionary through the natural, intended API.
like image 71
Nikolai Ruhe Avatar answered Sep 19 '22 10:09

Nikolai Ruhe


Apple Documentation: NSKeyValueCoding Protocol Reference

setValue:forKey:

Sets the property of the receiver specified by a given key to a given value.

Example:

[foo setValue:@"blah blah" forKey:@"stringOnFoo"];

setValue:forKeyPath:

Sets the value for the property identified by a given key path to a given value.

Example:

[foo setValue:@"The quick brown fox" forKeyPath:@"bar.stringOnBar"];
like image 21
ezekielDFM Avatar answered Sep 18 '22 10:09

ezekielDFM