我們都知道蘋果的KVO可以為我們提供觀察屬性的方法,它可以實現(xiàn)監(jiān)聽屬性的改變并得到通知。既然蘋果沒有給我們開源,那我們就來自己琢磨一下它究竟是如何工作的。
1 kvo的使用
我們首先來寫一個非常簡單的kvo使用,當(dāng)點擊屏幕時,可以得到kvo通知回調(diào),并且打印這個屬性的新值。

這些都是基本的kvo使用,這里就不做過多介紹啦。。。
2 假設(shè)kvo的實現(xiàn)原理
那這里我們就要思考了,既然是觀察屬性的變化,那我們自然就會聯(lián)想到setter方法,蘋果可以重寫這個類的setter方法,并且使用willChangeValueForKey和DidChangeValueForKey方法來監(jiān)聽屬性并發(fā)送通知,當(dāng)然又不可能直接加在People類里面,那么會不會是動態(tài)創(chuàng)建了一個類,繼承這個People類,改變這個類的isa指針,并且重寫屬性的方法呢?既然有了思路,那就一起來試試看吧。
當(dāng)然這么說也不是沒有根據(jù)的,我們在kvo這句代碼打個斷點,就可以看到原本isa指針是People,而執(zhí)行完成addObserver后就isa指針就變成了 NSKVONotifying_People,所以我們知道剛才的假設(shè)是成立的,雖然我們不能完全知道kvo底層到底是怎么實現(xiàn)的,不過卻可以用所學(xué)知識來手動實現(xiàn)一個kvo。

3 手動實現(xiàn)kvo
既然要實現(xiàn)kvo這個方法,那么一定要有addObserver這個方法,通過Definition我們可以看到,addObserver這個方法是NSObject的一個分類。
那么我們也來模仿一下,給NSObject寫一個分類,這里我準(zhǔn)備分4步來實現(xiàn)。
1.創(chuàng)建被觀察者的子類
2.修改調(diào)用者isa指針
3.重寫子類的set方法
4.發(fā)送通知
1、創(chuàng)建被觀察者的子類
首先我們創(chuàng)建一個NSObject的分類,給這個分類添加一個方法,由于不能和已經(jīng)存在的addObserver方法重名,我就在addObserver中間加了個Kvo,來方便區(qū)別這個我們自己寫的方法。
然后在NSObject+kvo.m里面來實現(xiàn)這個方法

到這里,我們的子類就已經(jīng)創(chuàng)建好了
2、修改調(diào)用者isa指針其實只要一句話

3、重寫set方法

這里我們可以拿到這個屬性的新值,可是父類卻不知道這個新值,這時我們通過msgSend來給父類發(fā)送消息,調(diào)用setName方法,并把新的name傳過去
為了驗證這里的代碼是否正確,我在viewController里面調(diào)用一下,這里已經(jīng)把原有的addObserver方法注釋掉,調(diào)用了我們自己的addKvoObserver方法,結(jié)果顯然是有效果的。

那么現(xiàn)在子類生成了,新值拿到了,isa指針也修改過了,set方法也重寫了,只剩下要給外界發(fā)送通知了。
4、發(fā)送通知
首先我們要保存這個對象,方便在下面取到,然后我們在setName方法里取到這個observer之后,用msgSend調(diào)用方法來發(fā)送通知。

最后我們就可以在viewController里修改屬性,并且獲得通知了。

至此,我們的手寫kvo就已經(jīng)實現(xiàn)了。
第一次寫文章,沒有什么架構(gòu)和排版,希望大家湊合看,提出各種問題。。。。
以后我會多多更新文章,方便大家互相學(xué)習(xí)技術(shù),覺得好的話記得關(guān)注我哦?。?!