views:

576

answers:

2

Currently I'm learning all the stuff around key-value coding.

In the docs they say:

Any object in the key path sequence that is not key-value coding compliant for the appropriate key receives a valueForUndefinedKey: message.

I try to imagine a situation where an object is not key-value coding compliant. How could that happen? When I subclass an UIView, that's obviously compliant, right? But when I just make my own object with NSObject as superclass, how's that? And when I make a class with no superclass, then for sure this is not k-v compliant?

+2  A: 

If you read carefully, you'll see it says "key-value coding compliant for the appropriate key". This means, basically, that you don't have the appropriate KVC methods for the key you asked for. So if I do [[NSString stringWithString:@"foo"] valueForKey:@"dippingSauce"], it will fall through to valueForUndefinedKey: because NSString is not KVC-compliant for the key "dippingSauce" — it doesn't have a dippingSauce instance method or a dippingSauce ivar.

Chuck
I get it :) so the whole KVC compliance stuff is not bound to the whole class, but to each instance variable or property. nice
Thanks
+2  A: 

It says "that is not key-value coding compliant for the appropriate key." What that means is that

@interface MyObject : NSObject {
  NSString *foo;
  NSString *bar;
}

@property (nonatomic, retain) NSString *foo;
@property (nonatomic, retain) NSString *bar;

@end

@interface MyObject

@synthesize foo;
@synthesize bar;

@end

Is compliant for "foo" and "bar", but not "baz."

For simple properties that is all there is to it, by default all NSObject subclasses implement basic KVC. It gets trickier with collections. In order for KVC to work correctly for collections (so you can do things like:

NSArray *people = ... ;
NSArray *firstNames = [people valueForKey:@"firstName"];

It requires you implement certain extra methods. In general the biggest user of that functionality is Cocoa bindings (which is not available on the iPhone) sourced out of CoreData (which generates that additional collection methods automatically anyway), so it still usually handled basically automatically. Generally people don't bother to implement full KVC support for dictionaries or arrays in their objects unless they intend to actually expose them. You can read about compliance in the KVC guide.

Louis Gerbarg
What extra methods are required? That should work as long as all the objects in `people` respond to `firstName`.
Chuck
ok so if I dont make a property for an instance variable, i.e. create no getter/setter, I can't access that via KVC?
Thanks
Chuck: sorry that example will in fact work, but some of the more complex using things like @distinctUnionOfSets etc may have issues. Thanks: No, properties are not necessary for KVC compliance, they are just got thing in general since they make you express the memory semantics of the objects.
Louis Gerbarg