8

as shown in this page

[self setValue:[NSNumber numberWithInt:intValue] forKey:@"myObject.value"];

The answer was that "of course, it's a key path not a single key", What does that mean?

Community
  • 1
  • 1
LolaRun
  • 5,526
  • 6
  • 33
  • 45

2 Answers2

15

A key is a string that identifies a property of an object. A key path is a list of keys separated by dots, used to identify a nested property.

Here's an example. If an object person has a property address, which itself has a property town you could get the town value in two steps using keys:

id address = [person valueForKey:@"address"];
id town = [address valueForKey:@"town"];

or in one step using a keyPath:

id town = [person valueForKeyPath:@"address.town"];

Have a look at Apple's docs on Key-Value Coding for further details.

Simon Whitaker
  • 20,506
  • 4
  • 62
  • 79
  • so the key must be the name of a property of the object being stored? if so then what's the alternative, for example like dictionaries or hashtables in java and C#? where keys could be any string or object? – LolaRun Nov 25 '10 at 08:53
  • 1
    @LolaRun Yes, the keys must be the property name. Or in the case of Dictionaries, the key is the key. See example code in [my answer](http://stackoverflow.com/a/20015365/642706) to another question: [Directly accessing nested dictionary values in Objective-C](http://stackoverflow.com/questions/4317760/directly-accessing-nested-dictionary-values-in-objective-c/20015365#20015365) – Basil Bourque Nov 16 '13 at 06:08
  • great example and explanation. – Yoon Lee Dec 29 '14 at 20:33
0

valueForKey vs valueForKeyPath

[Objective-C KVC]
[Swift KVC]

  • valueForKey is about KVC
  • valueForKeyPath is KVC + dot syntax

You are able to use valueForKeyPath for root properties, but you are not able to use valueForKey for nested properties

A has -> B has -> C
//root properties
B *b1 = [a valueForKey:@"b"];

B *b2 = [a valueForKeyPath:@"b"];

//nested properties
C *c1 = [a valueForKey:@"b.c"]; //[<A 0x6000016c0050> valueForUndefinedKey:]: this class is not key value coding-compliant for the key b.c. (NSUnknownKeyException)
   
C *c2 = [a valueForKeyPath:@"b.c"];

Additional context

//access to not existing
[a valueForKey:@"d"]; //runtime error: [<A 0x600003404600> valueForUndefinedKey:]: this class is not key value coding-compliant for the key d. (NSUnknownKeyException)

//they both return `id` that is why it is simple to work with them
id id1 = [a valueForKey:@"b"];
B *b1 = (B*) id1;//[b1 isKindOfClass:[B class]]
//or
B *b2 = [a valueForKey:@"b"];

//Wrong cast
C *c1 = [a valueForKey:@"b"];
[c1 fooC]; //-[B fooC]: unrecognized selector sent to instance 0x600001f48980 (NSInvalidArgumentException)
yoAlex5
  • 29,217
  • 8
  • 193
  • 205