iOS KVC Key Value Coding實現(xiàn)機制

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

KVC概述

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

KVC使用

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

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

KVC鍵值查找

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

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

    2、上面的setter方法沒找到,如果類方法accessInstanceVariablesDirectly返回YES。那么按 _key,_isKey,key,iskey的順序搜索成員名。(NSKeyValueCodingCatogery中實現(xiàn)的類方法,默認實現(xiàn)為返回YES)

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

  • valueForKey:的搜索方式

    1、首先按getKey,key,isKey的順序查找getter方法,找到直接調(diào)用。如果是BOOL、int等內(nèi)建值類型,會做NSNumber的轉(zhuǎn)換。

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

    3、還沒找到,查找countOfKey、enumeratorOfKey、memberOfKey格式的方法。如果這三個方法都找到,那么就返回一個可以響應(yīng)NSSet所有方法的代理集合。
    4、還是沒找到,如果類方法accessInstanceVariablesDirectly返回YES。那么按 _key,_isKey,key,iskey的順序搜索成員名。

    5、再沒找到,調(diào)用valueForUndefinedKey。

KVC實現(xiàn)分析

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

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

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

//會被編譯器處理成

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

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

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

  • (1)根據(jù)方法名找到運行方法的時候需要的環(huán)境參數(shù)
  • (2)他會從自己的isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實現(xiàn)接口。
  • (3)再直接查找得來的具體的實現(xià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)容

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