Tuesday, October 29, 2013

Key-Value Observing for the Mainstream

I was going to write about the rare NSHipster article that I wouldn’t recommend, but Damien DeVille already has:

The truth is, in practice it is very important to always use the context to differentiate between observed objects and not rely on the key path. We are working with an object-oriented language and we should always accommodate for the case where a class might be subclassed or a super class expecting a behavior that your own class will prevent.

[…]

Or even worse, would you ever consider handling a signal for a memory error due to calling free on a freed piece of memory because you couldn’t remember whether you previously retained this object and decided to release it anyway.

No. Because this is madness.

Update (2013-10-30): Damien DeVille has more on +keyPathsForValuesAffectingValueForKey::

I hope this helped you understand how the key dependency KVO mechanism works. As I said in the previous post, KVO has very simple rules and is very powerful, as long as you follow the rules.

2 Comments RSS · Twitter

I had a mild dislike of KVO until I implemented two-way bindings and an IB palette for my FileView framework. It turned into full-blown loathing after I discovered that the documentation was incomplete and was wrong about some key things. IIRC some of the options were also non-functional, depending on what OS version you're using (this was in the 10.5 era). On the plus side, that was the best way to learn how bindings worked, and at least I could debug them since I had the sourceā€¦unlike using Apple's bindings!

Though the advice might be bad, I agree that the KVO APIs are not friendly. I think one problem is the initial expectation that it would work similarly to NSNotificationCenter, given how similar the concept of an observer seems to be. But unlike NSNotificationCenter, you cannot use different callbacks for different notifications, you can subscribe more than once with the same observer, you have to balance your subscriptions/unsubscriptions (which in practice often means you have to keep track of wether you subscribed or not; or else have the subscription run for the lifetime of the object; and even then, there were issues with removing observers in `finalize` under GC). And having to declare a static object to use as the context does not feel it belongs with a modern language and API.

Nowadays, I only use KVO together with a wrapper object (in my case https://github.com/cparnot/PARViewController/blob/master/PARObjectObserver.h).

His initial post also contained factual errors about the need to implement `willChange...` and `didChange...` before ObjC 2.0, but that's been removed from the post.

Maybe he was for once a bit outside his comfort zone :-)

Leave a Comment