Defects of KVO
KVO(Key-Value Observing) is a very nice programming facility from Apple. Working together with KVC(Key-Value Coding), it makes the life of Apple developers a lot easier and happier.
However, I recently found some annoying problems of KVO while building some reusable programming components for Voodo and future iOS projects.
Observers can not be queried
Observers are stored in dictionaries1, so it should be very easy to query whether an object A is a registered observer of object B. But one can’t do that.
Unregistering an unregistered observer throws exception
One can not query whether A is an observer of B in the first place, and can neither try to unregister it from B when one wants to ensure that A is unregistered from B. It is just ridiculous! And why is removing a nonexistent observer so fatal while removing a nonexistent entry from a collection is reasonably ignored?2
Observers/observees don’t auto-dissolve the KVO relationship in dealloc
It can be easily done in KVO framework code since it already has the data structure keeping the observer-observee relationship information, and is very reasonable things to do – when any part of a relationship is gone the relationship is ended. Without the auto-unregistration, developers’ responsibility is unnecessarily heavier. In fact, it is no easy work in cases where observers outlive observees, because an observee needs to notify its observers of its death so the observers can detach themselves from the dying observee.3
All in all
KVO leaves some extra, tedious, and burdensome relationship management work to us while it could be easily and efficiently done at the root of itself.4
The KVO relationship management is especially stressful for observers watching many dynamic observees which is not unusual for generic components – UINavigationController and UITabBarController both manage a dynamic group of UIViewControllers and may observe some properties of them. It is even worse in my component because not only the observee but also the observed properties of them are dynamic.
-
See NSKeyValueObserving protocol’s observationInfo. ↩
-
See NSMutableArray’s removeObject: and NSMutableDictionary’s removeObjectForKey:. ↩
-
Normally it is the observers that are doing the KVO relationship management and it is the job of whoever did the connection to do the disconnection, but vice versa. ↩
-
Well, as Appler eskimo1 said in devforums, it is harder than one might think because
KVO needs to be both thread safe and GC clean, and must be careful to not impact the performance of code that isn’t using it
. ↩