深刻理解 KVC\KVO 實現機制 — KVC

KVC和KVO都屬於鍵值編程並且底層實現機制都是isa-swizzing,因此原本想放在一塊兒講的。可是篇幅有限因此就分紅了兩篇博文 KVO實現機制傳送門html

KVC概述

  • KVC是Key Value Coding的簡稱。它是一種能夠經過字符串的名字(key)來訪問類屬性的機制。而不是經過調用Setter、Getter方法訪問。
  • 關鍵方法定義在 NSKeyValueCodingProtocol
  • KVC支持類對象和內建基本數據類型。

KVC使用

  • 獲取值
    valueForKey: 傳入NSString屬性的名字。
    valueForKeyPath: 屬性的路徑,xx.xx
    valueForUndefinedKey 默認實現是拋出異常,可重寫這個函數作錯誤處理編程

  • 修改值
    setValue:forKey:
    setValue:forKeyPath:
    setValue:forUnderfinedKey:
    setNilValueForKey: 對非類對象屬性設置nil時調用,默認拋出異常。函數

KVC鍵值查找

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

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

    二、上面的setter方法沒找到,若是類方法accessInstanceVariablesDirectly返回YES。那麼按 _key,_isKey,key,iskey的順序搜索成員名。(NSKeyValueCodingCatogery中實現的類方法,默認實現爲返回YES)代理

    三、若是沒有找到成員變量,調用setValue:forUnderfinedKey:指針

  • valueForKey:的搜索方式code

    一、首先按getKey,key,isKey的順序查找getter方法,找到直接調用。若是是BOOL、int等內建值類型,會作NSNumber的轉換。htm

    二、上面的getter沒找到,查找countOfKey、objectInKeyAtindex、KeyAtindexes格式的方法。若是countOfKey和另外兩個方法中的一個找到,那麼就會返回一個能夠響應NSArray全部方法的代理集合的NSArray消息方法。對象

    三、還沒找到,查找countOfKey、enumeratorOfKey、memberOfKey格式的方法。若是這三個方法都找到,那麼就返回一個能夠響應NSSet全部方法的代理集合。
    四、仍是沒找到,若是類方法accessInstanceVariablesDirectly返回YES。那麼按 _key,_isKey,key,iskey的順序搜索成員名。

    五、再沒找到,調用valueForUndefinedKey。

KVC實現分析

KVC運用了isa-swizzing技術。isa-swizzing就是類型混合指針機制。KVC經過isa-swizzing實現其內部查找定位。isa指針(is kind of 的意思)指向維護分發表的對象的類,該分發表實際上包含了指向實現類中的方法的指針和其餘數據。

好比說以下的一行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表,值是還書指針IMP,SEL的名稱就是查表時所用的鍵。
SEL數據類型:查找方法表時所用的鍵。定義成char*,實質上能夠理解成int值。
IMP數據類型:他其實就是一個編譯器內部實現時候的函數指針。當Objective-C編譯器去處理實現一個方法的時候,就會指向一個IMP對象,這個對象是C語言表述的類型。

KVC的內部機制:
一個對象在調用setValue的時候進行了以下操做:

  • (1)根據方法名找到運行方法的時候須要的環境參數
  • (2)他會從本身的isa指針結合環境參數,找到具體的方法實現接口。
  • (3)再直接查找得來的具體的實現方法
相關文章
相關標籤/搜索