iOS KVC Key Value Coding實(shí)現(xiàn)機(jī)制

KVC和KVO都屬于鍵值編程而且底層實(shí)現(xiàn)機(jī)制都是isa-swizzing,所以本來想放在一起講的炮障。但是篇幅有限所以就分成了兩篇博文 KVO實(shí)現(xiàn)機(jī)制

KVC概述

  • KVC是Key Value Coding的簡稱。它是一種可以通過字符串的名字(key)來訪問類屬性的機(jī)制宅此。而不是通過調(diào)用Setter垒棋、Getter方法訪問。
  • 關(guān)鍵方法定義在 NSKeyValueCodingProtocol
  • KVC支持類對(duì)象和內(nèi)建基本數(shù)據(jù)類型偏螺。

KVC使用

  • 獲取值
    valueForKey: 傳入NSString屬性的名字行疏。
    valueForKeyPath: 屬性的路徑,xx.xx
    valueForUndefinedKey 默認(rèn)實(shí)現(xiàn)是拋出異常套像,可重寫這個(gè)函數(shù)做錯(cuò)誤處理

  • 修改值
    setValue:forKey:
    setValue:forKeyPath:
    setValue:forUnderfinedKey:
    setNilValueForKey: 對(duì)非類對(duì)象屬性設(shè)置nil時(shí)調(diào)用酿联,默認(rèn)拋出異常。

KVC鍵值查找

搜索單值成員
  • setValue:forKey:搜索方式

    1夺巩、首先搜索setKey:方法贞让。(key指成員變量名,首字母大寫)

    2柳譬、上面的setter方法沒找到喳张,如果類方法accessInstanceVariablesDirectly返回YES。那么按 _key美澳,_isKey销部,key,iskey的順序搜索成員名制跟。(NSKeyValueCodingCatogery中實(shí)現(xiàn)的類方法舅桩,默認(rèn)實(shí)現(xiàn)為返回YES)

    3、如果沒有找到成員變量雨膨,調(diào)用setValue:forUnderfinedKey:

  • valueForKey:的搜索方式

    1擂涛、首先按getKey,key哥放,isKey的順序查找getter方法歼指,找到直接調(diào)用爹土。如果是BOOL、int等內(nèi)建值類型踩身,會(huì)做NSNumber的轉(zhuǎn)換胀茵。

    2、上面的getter沒找到挟阻,查找countOfKey琼娘、objectInKeyAtindex、KeyAtindexes格式的方法附鸽。如果countOfKey和另外兩個(gè)方法中的一個(gè)找到脱拼,那么就會(huì)返回一個(gè)可以響應(yīng)NSArray所有方法的代理集合的NSArray消息方法。

    3坷备、還沒找到熄浓,查找countOfKey、enumeratorOfKey省撑、memberOfKey格式的方法赌蔑。如果這三個(gè)方法都找到,那么就返回一個(gè)可以響應(yīng)NSSet所有方法的代理集合竟秫。
    4娃惯、還是沒找到,如果類方法accessInstanceVariablesDirectly返回YES肥败。那么按 _key趾浅,_isKey,key馒稍,iskey的順序搜索成員名皿哨。

    5、再?zèng)]找到筷黔,調(diào)用valueForUndefinedKey往史。

KVC實(shí)現(xiàn)分析

KVC運(yùn)用了isa-swizzing技術(shù)。isa-swizzing就是類型混合指針機(jī)制佛舱。KVC通過isa-swizzing實(shí)現(xiàn)其內(nèi)部查找定位。isa指針(is kind of 的意思)指向維護(hù)分發(fā)表的對(duì)象的類挨决,該分發(fā)表實(shí)際上包含了指向?qū)崿F(xiàn)類中的方法的指針和其他數(shù)據(jù)请祖。

比如說如下的一行KVC代碼:

[site setValue:@"sitename" forKey:@"name"];

//會(huì)被編譯器處理成

SEL sel = sel_get_uid(setValue:forKey);
IMP method = objc_msg_loopup(site->isa,sel);
method(site,sel,@"sitename",@"name");

每個(gè)類都有一張方法表,是一個(gè)hash表脖祈,值是還書指針I(yè)MP肆捕,SEL的名稱就是查表時(shí)所用的鍵。
SEL數(shù)據(jù)類型:查找方法表時(shí)所用的鍵盖高。定義成char*慎陵,實(shí)質(zhì)上可以理解成int值眼虱。
IMP數(shù)據(jù)類型:他其實(shí)就是一個(gè)編譯器內(nèi)部實(shí)現(xiàn)時(shí)候的函數(shù)指針。當(dāng)Objective-C編譯器去處理實(shí)現(xiàn)一個(gè)方法的時(shí)候席纽,就會(huì)指向一個(gè)IMP對(duì)象捏悬,這個(gè)對(duì)象是C語言表述的類型。

KVC的內(nèi)部機(jī)制:
一個(gè)對(duì)象在調(diào)用setValue的時(shí)候進(jìn)行了如下操作:

  • (1)根據(jù)方法名找到運(yùn)行方法的時(shí)候需要的環(huán)境參數(shù)
  • (2)他會(huì)從自己的isa指針結(jié)合環(huán)境參數(shù)润梯,找到具體的方法實(shí)現(xiàn)接口过牙。
  • (3)再直接查找得來的具體的實(shí)現(xiàn)方法
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市纺铭,隨后出現(xiàn)的幾起案子寇钉,更是在濱河造成了極大的恐慌,老刑警劉巖舶赔,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扫倡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡竟纳,警方通過查閱死者的電腦和手機(jī)镊辕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚁袭,“玉大人征懈,你說我怎么就攤上這事】模” “怎么了卖哎?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長删性。 經(jīng)常有香客問我亏娜,道長,這世上最難降的妖魔是什么蹬挺? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任维贺,我火速辦了婚禮,結(jié)果婚禮上巴帮,老公的妹妹穿的比我還像新娘溯泣。我一直安慰自己,他們只是感情好榕茧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著用押,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上池充,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音收夸,去河邊找鬼坑匠。 笑死咱圆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的序苏。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼忱详,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼围来!你這毒婦竟也來了匈睁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤航唆,失蹤者是張志新(化名)和其女友劉穎胀蛮,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糯钙,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粪狼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了任岸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片再榄。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖享潜,靈堂內(nèi)的尸體忽然破棺而出困鸥,到底是詐尸還是另有隱情,我是刑警寧澤剑按,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布疾就,位于F島的核電站,受9級(jí)特大地震影響吕座,放射性物質(zhì)發(fā)生泄漏虐译。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一吴趴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦锣枝、人聲如沸厢拭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽供鸠。三九已至,卻和暖如春陨闹,著一層夾襖步出監(jiān)牢的瞬間楞捂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工趋厉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寨闹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓君账,卻偏偏與公主長得像繁堡,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乡数,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容