Getting started with Key-Value Observing

Getting started in Cocoa can be hard. Just learning the frameworks is a challenge.

Once you get to that point, most or your journey still lies ahead. If you were like me, you probably learned a lot about iPhone programming from online tutorials and books. Then one day, after your 16th tutorial and 3rd book, you looked around and said, “Now what?”

The truth is that technologies like Core Animation, Core Data, and Core Graphics are just tools. They are only a means to an end.

A full toolbox does not make a carpenter good. You still need experience, planning, and vision.

With this in mind, I want to talk about Key-Value Observing. This won’t be a full coding example, per se, but a discussion of how you may use this tool in your code.

Many readers may know the gist of KVO, as well as KVC and bindings. Although bindings are beyond the scope of this post, we will give a quick definition of keys and Key-Value Coding.

KVC is a technology that allows you to access an instance variable by using a string referred to as a key. So using an example:

Interface.png

To access are aptly named dictionary, we can type the two equivalent statements:

kvc.png

They do exactly the same thing, but in KVC we use supply keys using the “valueForKey:” method available to all NSObject subclasses.

To set this property we can use either of the following statements:

kvcgtters.png

This can get more complicated with key paths and some other things. If you would like more information, there are some great tutorials available here and here.

Now to KVO. For those who don’t know, KVO provides a mechanism to receive notifications that an instance variable, has been modified. Of course you know now we will be using keys to do this. First you register as an observer for the key:

setupobserver.png

(Note: I won’t engage in any “self=[super init]” talk here)

We simply registered the class to receive notifications about its own instance variable, but we could have easily selected an ivar of another object.

We also have set some options and a context here, but nothing that need be delved into for our discussion.

To receive the notification, we need to implement one method:

observe.png

Every time the instance variable is changed, this method will be called automagically.

Now that we have a very, very rudimentary understanding of what KVO (and KVC) are, we can begin to talk about how to use them.

One very common use of KVO is model observation. On stack overflow, I see many questions like: “If I have a variable in view controller A, how do I pass it to view controller B?” Of course the real problem is that we are asking the wrong question.

The right question is: “How can I get two view controllers to know about changes of a single variable?”

We know now that we can use KVO. What we want to do is make our views observe our models. By registering view controllers as observers to the model, we can have an unlimited of views showing and/or using the same data. This also gives us well defined MVC boundaries. What’s more, is that we will write almost no code to accomplish this feat.

As you will read elsewhere, KVO has some (few) disadvantages. The one that sticks out, is that it may make your code harder to debug. This is because it is hard to sometimes tell who is observing who. Otherwise this is a very elegant solution that will eliminate some of your glue code.

If you want to go deeper into Key-Value Observing you can read more here, here, here, and of course you can use Apple’s documentation.

What are some uses and patterns of KVO and KVC in your programming?

6 Comments

  1. Posted June 19, 2009 at 1:32 pm | Permalink

    Totally off topic…where did you get the Xcode theme and would you mind sharing it?

  2. Corey
    Posted June 19, 2009 at 9:37 pm | Permalink

    i got it from @dtm3dd. Check his blog post or his past tweets, I think it was called seaside or something similar.

  3. Terry
    Posted August 12, 2010 at 5:55 pm | Permalink

    Can KVO be used as the glue between the Model and View? So the Controller, using KVO, observes changes in the Model and updates the View, and vice versa?

  4. Corey
    Posted August 12, 2010 at 6:54 pm | Permalink

    That is a pretty typical use case. Since there are no bindings on the iPhone, however, you have to still need some “glue code” in your view controllers.

    Also, you do not want the model to observe the view, that makes it less portable. Your controllers should update the model directly.

  5. Terry
    Posted August 13, 2010 at 3:34 am | Permalink

    Thanks. Your explanation of KVO has made the MVC idea clearer for me. KVO should be more prominent in all the various iPhone programming books out there, if only to give people a tool to make apps more MVC complient.

    …on the other hand, it does seem that Apple could have a cleaner approach to implementing KVO in Objective-C. The current approach requires a lot of if statements (if keyPath isEqual..etc) in the observeValueForKeyPath method, if several keyPaths are being observed.
    A better implementation might be:
    [obj addObsever:self forKeyPath:@"person.name" usingSelector:@selector(nameChanged:)]
    So a separate method is fired directly when the keyPath’s value is changed.

  6. Corey
    Posted August 13, 2010 at 11:37 am | Permalink

    Actually you can google MAKVONotificationCenter, where Mike Ash has done just that. I use it myself and does make for cleaner code!

One Trackback

  1. By iPhoneKicks.com on June 5, 2009 at 6:20 am

    Getting started with Key-Value Observing …

    You’ve been kicked (a good thing) – Trackback from iPhoneKicks.com – iPhone SDK links, community driven…