KVO:鍵值監聽
KVO的本質是什么?
利用runtime的動態特性生成了一個子類,并讓instance對象的isa指向這個全新的子類
當修改instance對象的屬性時候,會調用Foundation的_NSSetXXXValueAndNotify方法,
其內部調用了willChangeValueForKey 父類原來的setter didChangeValueForKey ,其內部會觸發監聽器Observer的監聽方法 observeValueForKeyPath:ofObject:change:context:方法
如何手動觸發KVO?
直接調用 willChangeValueForKey和didChangeValueForKey方法
直接修改成員變量會觸發KVO么?
不會,因為沒有觸發set方法 ,可以通過willChangeValueForKey和didChangeValueForKey進行手動觸發
在沒有監聽對象的時候 該對象的isa指向的類中 是只有isa superclass set get方法等 沒有任何區別
如果增加監聽后 該對象的isa指向的是一個通過runtime動態添加新生成的NSKVONotifying_xxx子類 該類中自己實現了set方法 該類中的superClass指向的是原來的類 ,而該新生成的子類的isa指向的自己的元類對象
由上圖可以知道,原來的set方法里面生成了一個_NSSetXXValueAndNotify方法,內部調用了 willChangeVauleForKey 和didChangeValueForKey方法 中間調用了原有的super中的set方法進行賦值
調用didChangeValueForKey內部調用了observer的observerValueForKeyPath:ofObject:change:context:方法
如圖:
重寫了class方法為了是屏蔽內部實現,隱藏了NSKVONotifying_XXX類的存在