聊聊 KVC KVO

KVC

NSKeyValueCoding 協(xié)議 鍵值編碼(key-value)桅打,指定的key獲取對應(yīng)value;
一個類中的私有變量,不能直接通過Setter葛闷、Getter方法訪問霹陡。但是卻可以通過KVC來訪問和蚪。利用kvc的這個特性,我們可以訪問系統(tǒng)里的一些私有變量烹棉。

valueForKey:
setValue:@"" forKey:@"keypath";
可以直接設(shè)置key攒霹,keyPath 為屬性和成員變量名稱;Key:只能訪問當(dāng)前對象的屬性
KeyPath:能利用運(yùn)算符一層一層往內(nèi)部訪問屬性浆洗;

<1> .語法 和 kvc
在實(shí)現(xiàn)了訪問器方法的類中催束,使用點(diǎn)語法和KVC訪問對象其實(shí)差別不大,二者可以任意混用辅髓;

<2> kvc 中的數(shù)值和數(shù)據(jù)結(jié)構(gòu)

NSNumber 是一般基礎(chǔ)數(shù)據(jù)類型的對象泣崩;
NSValue 主要是對一些結(jié)構(gòu)體型的數(shù)據(jù)和自定義的數(shù)據(jù)結(jié)構(gòu)類型;

那么我們對應(yīng)屬性名稱作為 keyPath洛口,系統(tǒng)是如何幫助我們查找到對應(yīng)成員變量和屬性的呢矫付?

① 檢查是否存在-<key>、-is<key>(只針對布爾值有效)或者-get<key>的訪問器方法第焰,如果有可能买优,就是用這些方法返回值;
檢查是否存在名為-set<key>:的方法,并使用它做設(shè)置值杀赢。對于-get<key>和-set<key>:方法烘跺,將大寫Key字符串的第一個字母,并與Cocoa的方法命名保持一致脂崔;

②如果上述方法不可用滤淳,則檢查名為-_<key>、-_is<key>(只針對布爾值有效)砌左、-_get<key>和-set<key>:方法脖咐;
③如果沒有找到訪問器方法,可以嘗試直接訪問實(shí)例變量汇歹。實(shí)例變量可以是名為:<key>或
<key>;

④如果仍未找到屁擅,則調(diào)用valueForUndefinedKey:和setValue:forUndefinedKey:方法。這些方法的默認(rèn)實(shí)現(xiàn)都是拋出異常产弹,我們可以根據(jù)需要重寫派歌。

異常處理 valueForUndefinedKey:

/* Given that an invocation of -valueForKey: would be unable to get a keyed value using its default access mechanism, return the keyed value using some other mechanism. The default implementation of this method raises an NSUndefinedKeyException. You can override it to handle properties that are dynamically defined at run-time.
*/

對于 NSDictionary objectForkey: 與 valueForKey:區(qū)別

一般來說 key 可以是任意字符串組合,如果 key 不是以 @ 符號開頭痰哨,這時候 valueForKey: 等同于 objectForKey:胶果,如果是以 @ 開頭,去掉 key 里的 @ 然后用剩下部分作為 key 執(zhí)行 [super valueForKey:]作谭。

NSDictionary *dict = [NSDictionary dictionaryWithObject:@"theValue" forKey:@"@theKey"];
NSString *value1 = [dict objectForKey:@"@theKey"];
NSString *value2 = [dict valueForKey:@"@theKey"];

value1  ok, value2 crash 
NSUnknownKeyException’, reason: ‘[<__NSCFDictionary 0x892fd80> valueForUndefinedKey:]: 
在 KVC 里可以通過 property 同名字符串來獲取對應(yīng)的值稽物。 @"@theKey"會轉(zhuǎn)成@"theKey",沒有同名執(zhí)行valueForUndefinedKey 拋出異常折欠;

KVO

NSObject(NSKeyValueObserving)

  • 注冊監(jiān)聽
  • 監(jiān)聽事件處理
  • 取消監(jiān)聽

當(dāng)某個類的對象第一次被觀察時贝或,系統(tǒng)就會在運(yùn)行期動態(tài)地創(chuàng)建該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的 setter 方法锐秦。
派生類在被重寫的 setter 方法實(shí)現(xiàn)真正的通知機(jī)制咪奖,就如前面手動實(shí)現(xiàn)鍵值觀察那樣。這么做是基于設(shè)置屬性會調(diào)用setter方法酱床,通過下面兩個方法實(shí)現(xiàn):

  • (void)willChangeValueForKey:(NSString *)key
  • (void)didChangeValueForKey:(NSString *)key羊赵;
didChangeValueForKey 會處理:
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;

 
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context NS_AVAILABLE(10_7, 5_0);

KVO 和 NSNotificationCenter 蘋果實(shí)現(xiàn)是只保存了個對象的地址,并沒有在銷毀的時候置為nil扇谣。所以 addObserver后昧捷,必須要有remove操作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末罐寨,一起剝皮案震驚了整個濱河市靡挥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸯绿,老刑警劉巖跋破,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件簸淀,死亡現(xiàn)場離奇詭異,居然都是意外死亡毒返,警方通過查閱死者的電腦和手機(jī)租幕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拧簸,“玉大人劲绪,你說我怎么就攤上這事〗铺瘢” “怎么了珠叔?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵蝎宇,是天一觀的道長弟劲。 經(jīng)常有香客問我,道長姥芥,這世上最難降的妖魔是什么兔乞? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮凉唐,結(jié)果婚禮上庸追,老公的妹妹穿的比我還像新娘。我一直安慰自己台囱,他們只是感情好淡溯,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著簿训,像睡著了一般咱娶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上强品,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天膘侮,我揣著相機(jī)與錄音,去河邊找鬼的榛。 笑死琼了,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的夫晌。 我是一名探鬼主播雕薪,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼晓淀!你這毒婦竟也來了所袁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤要糊,失蹤者是張志新(化名)和其女友劉穎纲熏,沒想到半個月后妆丘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡局劲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年勺拣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鱼填。...
    茶點(diǎn)故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡药有,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出苹丸,到底是詐尸還是另有隱情愤惰,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布赘理,位于F島的核電站宦言,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏商模。R本人自食惡果不足惜奠旺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望施流。 院中可真熱鬧响疚,春花似錦、人聲如沸瞪醋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽银受。三九已至践盼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蚓土,已是汗流浹背宏侍。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蜀漆,地道東北人谅河。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像确丢,于是被迫代替她去往敵國和親绷耍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評論 2 359

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