在Apple的Key-Value Observing Implementation Details document中,它表示实现创建了一个转发setter方法的子类。子类替换原始类。
为什么不使用method_exchangeImplementations()
来调整方法呢?为什么要创建一个子类?
答案 0 :(得分:9)
因为当你调整方法时,你改变了类的所有实例的方法。 KVO通知设置器比非KVO通知设置器更昂贵,因此您只想将KVO通知设置器用于实际观察到的实例,而不是针对所有类实例。
KVO通知属性设定方法必须做什么?至少,它必须使用[self observationInfo]
检查是否有任何KVO观察员注册了该物业。这样就可以保证额外的消息发送。此外,默认情况下,observationInfo
存储在线程安全的全局哈希表中,因此符合KVO的setter必须获取锁并执行哈希查找 - 以确定是否存在任何KVO观察者注册
如果你对属性设置器进行调整,那么每个类的实例必须在每次使用setter时支付这个价格,即使只有一小部分类实例实际上已经注册了观察者。
Apple的KVO实现创建了一个KVO通知子类。当您在类的实例上注册KVO观察者时,它会将该单个实例的类更改为KVO通知子类。因此,只有实际观察到的实例必须使用更昂贵的KVO通知设置器。