In Apple's Key-Value Observing Implementation Details document, it says the implementation creates a subclass to forward setter methods. The subclass replaces the original class.
Why not just use method_exchangeImplementations()
to swizzle the methods? Why is creating a subclass necessary?
Because when you swizzle a method, you change the method for all instances of the class. A KVO-notifying setter is more expensive than a non-KVO-notifying setter, so you only want to use the KVO-notifying setter for instances that are actually observed, not for all instances of the class.
What does a KVO-notifying property setter method have to do? At a minimum, it has to check whether there are any KVO observers registered for the property, using [self observationInfo]
. So that's a guaranteed extra message send. In addition, by default, the observationInfo
is stored in a thread-safe global hash table, so the KVO-compliant setter has to acquire a lock and perform a hash lookup—just to find out if there are any KVO observers registered.
If you swizzle the property setter, then every instance of the class has to pay this price on every use of the setter, even if only a tiny fraction of the class instances actually have observers registered.
Apple's KVO implementation creates a KVO-notifying subclass instead. When you register a KVO observer on an instance of a class, it changes the class of that single instance to the KVO-notifying subclass. So only the instances that are actually observed have to use the more expensive KVO-notifying setter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With