In Bindings Hell

I’m trying to like Cocoa Bindings. I really am. But I’ve spent a lot of time today trying to convert Cocoalicious’ table management code to use bindings, and I’m really beginning to wonder if it’s worth the effort. As far as I can tell, here is what I have to do:

  1. Create a custom NSArrayController subclass. This is necessary because I want to do custom filtering (tags and searches). This is accomplished by adding instance variables to hold the current tag filter and search (along with appropriate accessors), and then overriding the arrangeObjects: method to perform the actual searching and return a filtered array.
  2. In Interface Builder, create an instance of this custom array controller.
  3. Add an instance variable to my application delegate to hold a reference to the array controller instance created in step 2, and then hook it up in IB.
  4. In Interface Builder, bind the post table’s columns’ “value” bindings to the array controller I created in step 2, using the appropriate model key path for each column, taking care, of course, that my model class is KVC compliant for those keys.
  5. In Interface Builder, bind the array controller’s “contentArray” binding to the nib’s File’s Owner (NSApplication), specifying as the model key path the key for the array instance variable in my application delegate.
  6. In my application delegate, implement application:delegateHandlesKey: and return yes for the model key path specified in step 4.
  7. Make sure that my application delegate is now fully to-many KVO compliant for the key specified in step 4. This means implementing, in addition to the standard accessor methods: countOfX, indexOfObjectInX:, valueInXAtIndex:, objectInXAtIndex:, insertInX:, and removeFromXAtIndex:. Admittedly, I’m still a bit uncertain about whether this step was necessary, but the app crashed with a “not KVC compliant” message until I implemented them.
  8. I now have to make sure that updated lists of posts that come up from my lower-level del.icio.us API are noticed by the array controller, which means I have to empty the existing post array every time the list is refreshed (which is not a simple task since NSArrayController provides no way to simply flush the current array) and refill it through my NSArrayController instance’s various “addObject:” methods. This is in contrast to my old method of simply releasing and replacing the model array for every refresh.

I’m not even sure if that’s a comprehensive or even correct list, because after a day of fiddling around with this, I still don’t have my table view displaying data. I can tell that my custom “arrangeObjects:” method is returning the correct list, but for some reason when “arrangedObjects” is then getting called to populate the table, it’s returning an empty array. I’m sure I’m missing something that I’m supposed to implement somewhere.

My point in relating all of this isn’t to diss Cocoa Bindings, which I find very elegant and still want very much to work with. I’m writing both to ask if anyone knows where I’m going wrong, and to see if anyone can explain to me why all of this is so much better than hooking up a table’s data source outlet and implementing three simple delegate methods. What do I gain by using bindings in this situation, aside from an app that uses bindings?

Leave a Reply