KVO and Blocks – The SD Version

A few months ago, Jonathan Wight posted some code called KVOBlocks on his blog that lets you use Snow Leopard’s Blocks to make Key-Value Observing a lot easier. His was really cool and I immediately began experimenting with it.

But being the kind of person that likes to know how things work, I immediately looked at his public API for this, and dug into his source code, and there’s a few things about KVOBlocks that I think could be a little better (and some style/taste differences, as well).

So, instead of rewriting his code to have a very different underlying design, I wrote my own NSObject category called SDKVOBlocks. It’s up on github and I’m hereby giving it a BSD-style license. The public API is linked here, for your convenience.

Let me go into a little detail about the differences between Jon’s code and mine:

A major issue I had with his API is that it requires the use of an identifier string when inserting a KVO block handler. I understand that technically it’s a requirement if developers are to be able to add or remove specific handlers for the same key path on the same object, but to me it seems like it’s really unnecessary for developers beyond that point. In fact, it feels cumbersome to be forced to come up with a random string simply for this purpose, rarely to be used again… My thinking is, assuming these unique identifiers are necessary, they should be created automagically for us, and given back in the return argument of the initial observing method, so we can optionally use it if we need to (or just ignore it if we choose). In this respect, the API I wrote is more like the new event observing API used inside NSEvent on 10.6.

A minor style issue I had with Jonathan’s code was in the “notificiation center” pattern that he used. It’s a fine pattern, don’t get me wrong. But it feels like it’s a little bulky and could be implemented more cleanly, especially under Snow Leopard. Specifically, it feels cumbersome that all objects have to report to a singleton controller object, which handles all the hard work. I’m sure this is slightly more efficient than putting the bulk work inside each NSObject via a category, but considering the code I pumped out was pretty small (9 lines of code for the observation method, at the time of writing), I felt it was fine to ditch this notification center pattern for something slimmer.

Specifically, the newer pattern I used was to create a (lazily loaded) dictionary as a pseudo-ivar of each object being observed, from within inside this category. (If you aren’t familiar with how to associate variables with arbitrary objects, check out this blog post I wrote detailing how it works and how to take advantage of it.) So, this dictionary now stores the “helper” objects, with their keys being their unique identifiers. This is opposed to having the global-singleton-center’s massive dictionary storing everyone’s specific helper objects and unique identifiers. I feel this is a cleaner solution, personally.

I hope anyone finds this new API as useful as I will!

(Note: I’m not sure it’s 100% ready for GC yet, but it should be damn near close, if not already there.)

Update: It seems Andy Matuschak has a very similar idea to mine, but I can’t find a link to the source of his code on his site (maybe it’s on his guthub). But nonetheless, I’ll be updating my code to reflect his API, since it has a few improvements from what I already have written (namely, automatic unregistering).

Update: Oh, it seems the top link on his page is the git gist, not a permalink like I usually assume. So, his source is here on github and his code actually looks cleaner than mine (and it uses object-association from 10.6 as well as GCD, which is also cool).

Printed from: http://www.degutis.org/blog/dev/2009/09/27/kvo-and-blocks-the-sd-version/ .
© 2010.

1 Comment   »

Trackbacks/Pingbacks

  1. I am not a Business – Degutis.org

RSS feed for comments on this post , TrackBack URI

Leave a Reply