KVC和KVO都屬於鍵值編程並且底層實現機制都是isa-swizzing,因此原本想放在一塊兒講的。可是篇幅有限因此就分紅了兩篇博文 KVO實現機制傳送門html
獲取值
valueForKey: 傳入NSString屬性的名字。
valueForKeyPath: 屬性的路徑,xx.xx
valueForUndefinedKey 默認實現是拋出異常,可重寫這個函數作錯誤處理編程
修改值
setValue:forKey:
setValue:forKeyPath:
setValue:forUnderfinedKey:
setNilValueForKey: 對非類對象屬性設置nil時調用,默認拋出異常。函數
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運用了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的時候進行了以下操做: