Key-Value Observing Done Right. Again.
May 21, 2010 04:36 PM
| Cocoa, Development, Mac
| Permalink
I love using KVO for all sorts of things: side-effect, flagging UI as dirty, resetting caches, …
Writing the observeValueForKeyPath:ofObject:change:context: method has long since become tedious. So I created a TextExpander snippet to write it for me.
Still, I don't quite like it relying of string comparisons (which I use for context). And I regularly find myself forgetting to unregister observers.
Mike Ash wrote a interesting blog post where he makes a couple of good points against the current KVO API. The most important of which, I think, is the fact unregistering an observer might actually break behavior upon which the superclass relies.
Andy Matuschak has proposed a very convenient API which uses blocks to handle observation callbacks. While I love this solution, I found it to still have a couple of drawbacks:
Inspired by Mike's and Andy's writings and work, I have come up with my own implementation: HHKeyValueObserver.
Retain cycles may be avoided by referring to the observed object by the way of observationInfo.observee.
Writing the observeValueForKeyPath:ofObject:change:context: method has long since become tedious. So I created a TextExpander snippet to write it for me.
Still, I don't quite like it relying of string comparisons (which I use for context). And I regularly find myself forgetting to unregister observers.
Mike Ash wrote a interesting blog post where he makes a couple of good points against the current KVO API. The most important of which, I think, is the fact unregistering an observer might actually break behavior upon which the superclass relies.
Andy Matuschak has proposed a very convenient API which uses blocks to handle observation callbacks. While I love this solution, I found it to still have a couple of drawbacks:
- Andy's KVO+Blocks requires Mac OS X Snow Leopard. It relies not only on blocks, but also on associated objects and Grand Central Dispatch.
- Code is not always easer to read when the callback block is written where it is registered. At times, I would prefer a traget+action setup
- KVO+Blocks make it all too easy to create retain cycles: referencing an instance variable from within the block retains the owning object.
Inspired by Mike's and Andy's writings and work, I have come up with my own implementation: HHKeyValueObserver.
- Works on both Leopard and Snow Leopard. Relies on HHAssociatedObjects
- Target action mechanism with the following signatures: actionWithInfo:change: or actionWithInfo:
- Uses blocks where available
- Unregisters automatically on dealloc of the observer
Retain cycles may be avoided by referring to the observed object by the way of observationInfo.observee.
Comments