iOS學(xué)習(xí)之徹底搞清楚KVC/KVO

這篇主要講KVO的底層原理,順便講一下KVC。

先說一下KVC吧,KVC(key-value-coding)提供了一種通過字符串訪問對象屬性的機制,而不是調(diào)用對象的setter、getter方法。NSObject一個分類中實現(xiàn)了KVC,所以O(shè)C中所有對象都可以使用KVC。

對于對象的成員變量使用點語法(setter和getter方法)和KVC差別不大,但KVC神奇的是可以訪問私有屬性,也就是沒有提供setter和getter方法的屬性。舉個例子:

UIPageControl*pageControl = [[UIPageControlalloc] init];

?[pageControl setValue:[UIImageimageNamed:@"xxx.png"] forKeyPath:@"_pageImage"];

?[pageControl setValue:[UIImageimageNamed:@"xxx.png"] forKeyPath:@"_currentPageImage"]

_pageImage和_currentPageImage并不是UIPageControl對外公布的屬性,直接用點語法是訪問不到的,所以這里就使用了KVC進行賦值。

接著來講今天的重點:KVO(Key-Value-Observe)

KVO本質(zhì)上是觀察者模式的一種實現(xiàn),它提供一種機制,當(dāng)指定對象的屬性被修改后,則對象就會接受到通知。簡單的說,就是每次指定的被觀察的對象的屬性被修改后,KVO就會自動通知相應(yīng)的觀察者了。具體用法:

?Person?*p?=?[[Person?alloc]?init];??

?p.age?=?20; ? //原始值

?[p?addObserver:self?forKeyPath:@"age"?options:NSKeyValueObservingOptionOld?|?NSKeyValueObservingOptionNew?context:nil];??//注冊觀察者 ?

p.age=30;//修改值,此時便會觸發(fā)KVO提供的監(jiān)聽函數(shù):

-?(void)observeValueForKeyPath:(NSString?*)keyPath?ofObject:(id)object?change:(NSDictionary?*)change?context:(void?*)context?{??

????NSLog(@"%@對象的%@屬性改變了,由舊值%@改變?yōu)樾轮?@",?object,?keyPath,?change[@"old"],?change[@"new"]);??

}??

那么KVO具體是怎么實現(xiàn)的呢?

一句話總結(jié):對象在第一次添加監(jiān)聽的時候,系統(tǒng)會動態(tài)的新生成一個原對象類的子類,結(jié)合上面的例子就是NSKVONotifying_Person類,然后重寫該子類的setter方法,重寫的setter方法里面回調(diào)用willChangeValue和didChangeValue方法。同時,原對象的isa指針會指向新生成的子類。這樣,當(dāng)對象再調(diào)用屬性的setter方法時,其實調(diào)用的是子類的settet方法,從而實現(xiàn)屬性變化的監(jiān)聽。

這里是通過runtime動態(tài)生成類,涉及到方法有:

object_getClass(p)//獲得對象所屬的類,也就是isa指針

object_setClass(p, newClass);//設(shè)置對象所屬的類,改變isa指針的指向

class_addMethod(newClass,selectorName,?(IMP)newsetter,types)//類添加方法及實現(xiàn)

Class newClass=objc_allocateClassPair(originClass,?kvoClassName.UTF8String,?0)//新申請指定名字的類

objc_registerClassPair(newClass)//向系統(tǒng)注冊新申請的類

總結(jié):其實是新的類,新的方法去做的監(jiān)聽,雖然看上去像是原來的類。

?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,067評論 0 9
  • 上半年有段時間做了一個項目,項目中聊天界面用到了音頻播放,涉及到進度條,當(dāng)時做android時候處理的不太好,由于...
    DaZenD閱讀 3,101評論 0 26
  • KVC 什么是 KVC KVC 是 Key-Value-Coding 的簡稱。 KVC 是一種可以直接通過字符串的...
    LeeJay閱讀 2,268評論 6 41
  • KVC 什么是KVC KVC是Key-Value-Coding 的簡稱。 KVC是一種可以直接通過字符串的名字ke...
    Jack_deng閱讀 1,188評論 0 0
  • 本篇會對KVO的實現(xiàn)進行探究,不涉及太多KVO的使用方法,但是會有一些使用時的思考。 一、使用上的疑問 1.key...
    奮拓達閱讀 568評論 0 2

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