我們都知道蘋果的KVO可以為我們提供觀察屬性的方法肆汹,它可以實(shí)現(xiàn)監(jiān)聽屬性的改變并得到通知。既然蘋果沒有給我們開源窍侧,那我們就來自己琢磨一下它究竟是如何工作的县踢。
1 kvo的使用
我們首先來寫一個(gè)非常簡單的kvo使用,當(dāng)點(diǎn)擊屏幕時(shí)伟件,可以得到kvo通知回調(diào)硼啤,并且打印這個(gè)屬性的新值。
這些都是基本的kvo使用斧账,這里就不做過多介紹啦谴返。。咧织。
2 假設(shè)kvo的實(shí)現(xiàn)原理
那這里我們就要思考了嗓袱,既然是觀察屬性的變化,那我們自然就會(huì)聯(lián)想到setter方法习绢,蘋果可以重寫這個(gè)類的setter方法渠抹,并且使用willChangeValueForKey和DidChangeValueForKey方法來監(jiān)聽屬性并發(fā)送通知,當(dāng)然又不可能直接加在People類里面闪萄,那么會(huì)不會(huì)是動(dòng)態(tài)創(chuàng)建了一個(gè)類梧却,繼承這個(gè)People類,改變這個(gè)類的isa指針败去,并且重寫屬性的方法呢放航?既然有了思路,那就一起來試試看吧圆裕。
當(dāng)然這么說也不是沒有根據(jù)的广鳍,我們?cè)趉vo這句代碼打個(gè)斷點(diǎn),就可以看到原本isa指針是People吓妆,而執(zhí)行完成addObserver后就isa指針就變成了 NSKVONotifying_People赊时,所以我們知道剛才的假設(shè)是成立的,雖然我們不能完全知道kvo底層到底是怎么實(shí)現(xiàn)的耿战,不過卻可以用所學(xué)知識(shí)來手動(dòng)實(shí)現(xiàn)一個(gè)kvo蛋叼。
3 手動(dòng)實(shí)現(xiàn)kvo
既然要實(shí)現(xiàn)kvo這個(gè)方法,那么一定要有addObserver這個(gè)方法,通過Definition我們可以看到狈涮,addObserver這個(gè)方法是NSObject的一個(gè)分類狐胎。
那么我們也來模仿一下,給NSObject寫一個(gè)分類歌馍,這里我準(zhǔn)備分4步來實(shí)現(xiàn)握巢。
1.創(chuàng)建被觀察者的子類
2.修改調(diào)用者isa指針
3.重寫子類的set方法
4.發(fā)送通知
1、創(chuàng)建被觀察者的子類
首先我們創(chuàng)建一個(gè)NSObject的分類松却,給這個(gè)分類添加一個(gè)方法暴浦,由于不能和已經(jīng)存在的addObserver方法重名,我就在addObserver中間加了個(gè)Kvo晓锻,來方便區(qū)別這個(gè)我們自己寫的方法歌焦。
然后在NSObject+kvo.m里面來實(shí)現(xiàn)這個(gè)方法
到這里,我們的子類就已經(jīng)創(chuàng)建好了
2砚哆、修改調(diào)用者isa指針其實(shí)只要一句話
3独撇、重寫set方法
這里我們可以拿到這個(gè)屬性的新值,可是父類卻不知道這個(gè)新值躁锁,這時(shí)我們通過msgSend來給父類發(fā)送消息纷铣,調(diào)用setName方法,并把新的name傳過去
為了驗(yàn)證這里的代碼是否正確战转,我在viewController里面調(diào)用一下搜立,這里已經(jīng)把原有的addObserver方法注釋掉,調(diào)用了我們自己的addKvoObserver方法槐秧,結(jié)果顯然是有效果的啄踊。
那么現(xiàn)在子類生成了,新值拿到了刁标,isa指針也修改過了社痛,set方法也重寫了,只剩下要給外界發(fā)送通知了命雀。
4、發(fā)送通知
首先我們要保存這個(gè)對(duì)象斩箫,方便在下面取到吏砂,然后我們?cè)趕etName方法里取到這個(gè)observer之后,用msgSend調(diào)用方法來發(fā)送通知乘客。
最后我們就可以在viewController里修改屬性狐血,并且獲得通知了。
至此易核,我們的手寫kvo就已經(jīng)實(shí)現(xiàn)了匈织。
第一次寫文章,沒有什么架構(gòu)和排版,希望大家湊合看缀匕,提出各種問題纳决。。乡小。阔加。
以后我會(huì)多多更新文章,方便大家互相學(xué)習(xí)技術(shù)满钟,覺得好的話記得關(guān)注我哦Jだ啤!湃番!