Since Objective-C 2.0, we’ve had @properties and autogenerated accessor methods. So today, what is the point of key-value coding? Under what circumstances is it preferable to write
[myObject setValue:foo forKey:@"bar"];
instead of writing
[myObject setBar:foo];
or even
myObject.bar = foo;
I keep seeing articles and documentation making use of KVC, but always in a way where it seems like simply using properties would be better. So why would I ever use KVC? Thanks for any and all insight.
It’s almost never preferable to write out
[myObject setValue:foo forKey:@"bar"]by hand, with a literal@"bar". We usually use KVC to access a property when we don’t know which property we want to access until runtime.One example is an outlet in a xib. When you connect a text field’s delegate outlet to the File’s Owner in the xib, the xib records the connection as an object with three fields:
@"delegate"At runtime, the xib loader (part of the UIKit framework) deserializes the text field. Then it deserializes the connection object and uses it to establish the connection that you wired up in the xib. The xib loader has to set a property of the text field (the
delegateproperty), but it doesn’t know which property until it loads the xib at runtime, long after both your app and the UIKit framework were compiled.Another example of not knowing which property to access until runtime is the (little-known) ability of Core Animation to animate a custom property of your
CALayersubclass. Say you create a subclass ofCALayercalledPolygonLayer, with a property namedsides. You can animate thesidesproperty using a standardCABasicAnimation:Presto, Core Animation will animate your layer’s
sidesproperty from 3 to 9 and back. Yet the source code of Core Animation doesn’t know anything about yoursidesproperty. (Check out this question for more details.)There are times we use KVC even though we know the property at compile-time. One example is when we want to take advantage of extra work KVC will do for us. For example, if you have an
NSArrayfull ofPersonobjects, and you want to get an array of every person’s first name, you could write this:But this is a case where KVC has a feature that makes it simpler. If you access a property of an array using KVC, KVC will actually access that property of every element in the array for you:
Another example where we might use KVC even though we know the property at compile-time is when the property is not statically declared as part of the class. For example, each NSManagedObject (part of Core Data) dynamically gives itself properties based on whatever entity that instance of
NSManagedObjectis representing. You can access those properties using KVC, although generally we prefer to declare them in a subclass ofNSManagedObjector in a category ofNSManagedObject.