4.3 KVC/KVO —— KVC的實現(xiàn)原理,如何避免產生崩潰

?xml version="1.0" encoding="UTF-8"?

KVC中最常見的異常就是不小心使用了錯誤的Key碌上,或者在設值中不小心傳遞了nil的值

因為KVC傳遞進去的值和取出來的值都是id類型倚评,取值時KVC為結構體和變量類型是值類型的都會被封裝為NSNumber或者NSValue返回回來,但是設置值的時候就需要自己去做這個轉換了馏予,也就是說開發(fā)者需要自己擔保類型的正確性天梧,運行時OC會在發(fā)送消息的時候檢查類型,所以當你給一個非對象傳一個nil進去就會有問題霞丧。

如何避免產生崩潰:

崩潰的原因是找不到對應的key呢岗,很多時候是手寫字符串錯誤,為了避免這種情況,?我們通過@selector()獲取到方法的SEL后豫,然后通過NSStringFromSelector()將SEL反射為字符串悉尾。這樣在@selector()中傳入方法名的過程中,編譯器會有合法性檢查挫酿,如果方法不存在或未實現(xiàn)會報黃色警告构眯。

解決產生的崩潰:

①.當根據(jù)KVC的搜索規(guī)則,沒有搜索到對應的key或者keypath饭豹,會調用下面兩個相對應的異常方法鸵赖,兩個方法的默認實現(xiàn)是拋出異常從而產生的崩潰。解決方法是重寫下邊兩個方法拄衰,一般是打印沒找到的key它褪。

valueForUndefinedKey:

setValue: forUndefinedKey:

②.當通過KVC給某個非對象的屬性賦值為nil時,會調用這個方法翘悉,從而拋出異常茫打。

setNilValueForKey:

實現(xiàn)原理,或者說KVC是怎么尋找key的妖混?

①當調用setValue:forKey:方法的時候:

首先程序會調用set<Key>屬性值方法老赤,也就是先找setter方法。

如果沒有找到制市,KVC會檢查+ (BOOL)accessInstanceVariablesDirectly方法的返回值抬旺,默認返回YES,那么系統(tǒng)會遵循KVC的搜索原則即先去搜索該類里有沒有_<key>命名的變量名祥楣,無論在類的哪里定義开财,也無論什么修飾符,只要存在KVC都可以對其進行賦值误褪。

如果set<Key>和_<key>都沒有找到责鳍,那么再找_is<Key>的成員變量,再沒有兽间,再找<key>和is<Key>的成員變量历葛,找到了賦值。

如果set方法和四種成員變量都沒有嘀略,系統(tǒng)調用setValue:forUNdefinedKey:方法恤溶,默認是拋出異常。

如果+ (BOOL)accessInstanceVariablesDirectly方法的返回NO屎鳍,那么不再去找四種成員變量直接調用setValue:forUNdefinedKey:

②當調用valueForKey:方法的時候:

首先按get<Key>,<key>,is<Key>的順序方法查找getter方法宏娄。

如果上邊的方法里沒有找到,KVC會查找countOf<Key>,objectIn<Key>AtIndex,<Key>AtIndex格式的方法,是否有被實現(xiàn)逮壁,如果這其中countOf<Key>和objectIn<Key>AtIndex,<Key>AtIndex中兩個方法中任一個方法實現(xiàn)了孵坚,那么會返回一個可以響應NSArray所有方法的代理集合類名叫做NSKeyValueArray粮宛。 給這個代理集合發(fā)送NSArray的方法,就會以countOf<Key>,objectIn<Key>AtIndex,<Key>AtIndex就會以這幾個方法的形式返回卖宠。

如果上邊的方法里沒有找到巍杈,KVC會查找countOf<Key>,enumeratorOf<Key>,memberOf<Key>格式的方法,是否有被實現(xiàn)扛伍,如果有這三個方法都被實現(xiàn)筷畦,會返回一個可以響應NSSet所有方法的代理集合。

如果還是沒有找到刺洒,再檢查類方法+ (BOOL)accessInstanceVariablesDirectly,默認返回yes鳖宾,那么和先前的設值一樣,會按_<key>,_is<Key>,<key>,is<Key>的順序搜索成員變量名逆航。返回NO的話鼎文,那么會直接調用valueForUndefinedKey:。

還沒有找到的話因俐,調用valueForUndefinedKey:拇惋。

比如一個類實現(xiàn)了下圖所示的方法,


當調用[obj valueForKey:@“numbers”],的時候抹剩,如果找不到三種get方法撑帖,那么此時會返回一個叫做NSKeyValueArray的類。


當你給這個類發(fā)送NSArray的方法時澳眷,就會調用上邊你所實現(xiàn)的方法胡嘿,比如調用[ar count]就會調用你實現(xiàn)的countOfNumbers方法。調用ar[0],就會調用你實現(xiàn)的objectInNumbersAtIndex:方法钳踊。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末灶平,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子箍土,更是在濱河造成了極大的恐慌罐监,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沟堡,死亡現(xiàn)場離奇詭異矢空,居然都是意外死亡,警方通過查閱死者的電腦和手機屁药,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趾娃,“玉大人,你說我怎么就攤上這事抬闷「唬” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵眷茁,是天一觀的道長炕泳。 經常有香客問我,道長蔼卡,這世上最難降的妖魔是什么喊崖? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮雇逞,結果婚禮上荤懂,老公的妹妹穿的比我還像新娘。我一直安慰自己塘砸,他們只是感情好节仿,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著掉蔬,像睡著了一般廊宪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上女轿,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天箭启,我揣著相機與錄音,去河邊找鬼蛉迹。 笑死傅寡,一個胖子當著我的面吹牛,可吹牛的內容都是我干的北救。 我是一名探鬼主播荐操,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼珍策!你這毒婦竟也來了托启?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤攘宙,失蹤者是張志新(化名)和其女友劉穎屯耸,沒想到半個月后拐迁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體唠亚,經...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡灶搜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鹏溯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丙挽。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡颜阐,死狀恐怖凳怨,靈堂內的尸體忽然破棺而出肤舞,到底是詐尸還是另有隱情李剖,我是刑警寧澤囤耳,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站聪铺,受9級特大地震影響铃剔,放射性物質發(fā)生泄漏。R本人自食惡果不足惜凤类,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一谜疤、第九天 我趴在偏房一處隱蔽的房頂上張望夷磕。 院中可真熱鬧坐桩,春花似錦绵跷、人聲如沸碾局。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽埋合。三九已至萄传,卻和暖如春秀菱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赶么。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工辫呻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人祟昭。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像础钠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子废累,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345