KVO究竟干了什么?

學(xué)習(xí)記錄,僅供參考。歡迎指正?。?!

本質(zhì)是 調(diào)用了 屬性的 setter方法


前提 ? 新建 ?MLPerson類, 設(shè)置 int類型的age屬性

一、 設(shè)置屬性的值 ?添加KVo監(jiān)聽 ?查看監(jiān)聽前后的類對象的地址值變化

1. 這里使用 runtime 的API ?object_getClass?獲取實例對象 的isa指向的類對象

01

由此可見,person1實例對象 設(shè)置KVO監(jiān)聽之后,isa指向的類對象發(fā)生了變化,指向了一個由runtime動態(tài)生成的一個類 NSKVONotifying_XXX. 且這個類是 原來類XXX的一個子類。

二、查看添加KVO監(jiān)聽前后 元類對象的變化

設(shè)置監(jiān)聽前后的 類對象也發(fā)生了變化

說明:新生成的 子類 NSKVONotifying_XXX 的isa 指向的是 一個新的元類對象。

元類對象地址值

三、查看添加監(jiān)聽前后的方法的具體實現(xiàn)

設(shè)置監(jiān)聽之前:調(diào)用的是 MLPerson 里邊的 setAge:方法

設(shè)置監(jiān)聽之后:調(diào)用的是新的子類里邊的 setAge:方法,只不過 里邊調(diào)用了 Foundation框架 里邊的 _NSSetIntValueAndNofify方法

設(shè)置KVO監(jiān)聽前后方法的具體實現(xiàn)

四、窺探?_NSSetIntValueAndNofify 方法實現(xiàn)

1、 當(dāng)監(jiān)聽到 person1 的age屬相值發(fā)生了變化之后,首先調(diào)用 新生成的子類的 setAge:方法?

? ? ? ? setAge:方法里邊調(diào)用的是 Foundation 框架 的 _NSSetIntValueAndNotify方法

? ? ? ? 右下圖可知

_NSSetIntValueAndNotify的內(nèi)部實現(xiàn)? ? ? ? ? ??

? ? ? ? ①.先調(diào)用了 willChangeValueForKey:方法

? ? ? ? ②.接著調(diào)用 父類的 setAge:方法(也就是MLPerson里邊的setAge方法,使age的值真正發(fā)生變化)

? ? ? ? ③. 發(fā)生變化之后 會接著調(diào)用?didChangeValueForKey: 方法

? ? ? ? ? ? 在此方法內(nèi)部,通知監(jiān)聽器 某個對象的 屬性值 發(fā)生了變化 ?接著觸發(fā) KVO的監(jiān)聽方法 ??- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context;

_NSSetIntValueAndNofify

五、如果修改了 成員變量會不會觸發(fā)KVO?

不會。因為沒有調(diào)用 setter方法

修改成員變量不會觸發(fā)KVO監(jiān)聽

六、如何手動觸發(fā)KVO

手動調(diào)用 ?willChangeValueForKey ?和 ?didChangeValueForKey方法

手動觸發(fā)KVO
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容