KVO? KVC? Say what? Key-Value Observing and Key-Value Coding, that's what. As an introduction to Apple's new Cocoa/Objective-C API called Core Data, Marcus Zarra shows you why KVO/KVC is an incredibly useful feature in its own right and deserves the attention of any developer new to the Cocoa/Objective-C arena.

Like this article? We recommend

Every Java developer has learned some shortcuts to create the dreaded getters
and setters. Some use an IDE that produces these necessary but frustrating
methods; some use cut and paste, complicated macros, or (worse) write them by
hand. Some other languages have figured out ways to eliminate the necessity of
writing getters and setters by generating them automatically or simply
recommending accessing the fields directly.

Cocoa/Objective-C has another solution to the ugliness that is getters and
setters. This solution is Key Value Coding and Key Value Observing, KVO and KVC
for short.

Like Reflection, Sort Of

Starting with the basics, KVC is a way of accessing the fields stored in a
class instance in a way that is very similar to Java's Reflection API.
Take, for example, the following Objective-C header:

Normally, to access any of these values you would send a message to the
object such as [reference value1], which would return a pointer to value1.
However, with KVC you instead send a message to the Key-Value protocol as
follows:

[reference valueForKey:@"value1"];

This method will return the pointer to value1 inside of the object reference.
In addition to being able to send messages to the proper getters, this method
will also look for instance variables inside of the receiving object that match
the name passed in. Therefore, this same method can reference value3 in the
header above:

[reference valueForKey:@"value3"];

Thus, both of them are accessed the same way, even though one has an accessor
method, and the other does not. In addition to the straightforward accessor
methods and instance variables, this method can also resolve isXXX properly.
Therefore, the following will access the method isFlagValue instead of accessing
the instance variable directly:

[reference valueForKey:@"flagValue"];

The above method will return an NSNumber instead of a BOOL. Because BOOL is a
primitive and not a class, it is auto-boxed into an NSNumber.

It is also possible to set values using this same protocol. Instead of
calling the following:

[reference setValue1:@"test"];

an instance variable would be set as follows:

[reference setValue:@"test" forKey:@"value1"];

Although this is a bit more long-winded then calling the setter methods
directly, it is more consistent and allows direct access to the instance
variables within an object without knowing whether there is an accessor method.
In addition, if an accessor method is either added or removed at some later
date, it does not require any additional code changes.