kvo 與 kvc <2>

8.1: kvo 與 kvc 展開

? ? ?1:KVO

? ? ? ? ? ? KVO(Key-Value-Observing)鍵值觀察总棵,其技術(shù)原理就是通過 isa waizzle 技術(shù)添加被觀察對象中間類盗棵,并重新寫相應(yīng)的方法來監(jiān)聽鍵值變化牡肉。當(dāng)被觀察的對象屬性被修改后搏讶,則對象回接收到通知,即每次指定的被觀察對象的屬性被修改后呼巴,kvo就會自動通知相應(yīng)的觀察者影钉。

? ? ? ? ? ? isa swizzle 不同于method swizzle,其交換的是isa,對象的isa 指針式定義了它的類录粱,所以ISA swizzling 指修改對象所指向的類腻格,KVO則是使用該技術(shù)實現(xiàn)的,還有zombie objects檢測也用到了該技術(shù),而method swizzle交換的是method

? ? ? ? 2:KVO引起的crash 情況如下

? ? ? ? ? ? 2.1* observer 已銷毀啥繁,但是未及時移除監(jiān)聽荒叶;

? ? ? ? ? ? 2.2* addObserver 與 removeObserver 不匹配

? ? ? ? ? ? ? ? 1:移除了未注冊的觀察者,但是未及時移除監(jiān)聽

? ? ? ? ? ? ? ? 2:重復(fù)移除多次输虱,移除次數(shù)多于添加次數(shù)些楣,導(dǎo)致崩潰。

? ? ? ? ? ? ? ? 3:重復(fù)添加多次宪睹,雖然不會崩潰愁茁,但是發(fā)生改變時,也同時會被觀察多次亭病。

? ? ? ? ? ? 2.3*添加了觀察者鹅很,但未實現(xiàn)observerValueForKeyPath:ofObject:change:context: 方法,導(dǎo)致崩潰.

? ? ? ? ? ? 2.4*添加或移除時 keypath == nil 罪帖,導(dǎo)致崩潰.

? ? ? ? 通過如上場景就可以發(fā)現(xiàn)其實kvo 崩潰的主要原因是觀察者管理混亂促煮,特別是觀察者關(guān)系復(fù)雜時邮屁,開發(fā)者容易導(dǎo)致混亂。

? ? ? ? ? ? 如下圖所示:


圖1


? ? ? ? 那如何管理呢菠齿? 既然觀察者都是開發(fā)者來管理佑吝,由人來管理必然會出現(xiàn)失誤的時候,那我們是否能通過一個代理對象來管理绳匀?

? ? ? ? ? ? 答案:yes芋忿!

圖2


? ? ? ? 3:具體實現(xiàn)如下:

? ? ? ? ? ? 1:通過Method Swizzle方法調(diào)配交換KVO相應(yīng)的方法到NSObject基類,如下:

圖3

? ? ? ? ? ? 2: 然后在觀察者和被觀察者之間建立一個 KVODelegate 對象疾棵,

? ? ? ? ? ? ? ? 兩者之間通過 KVODelegate 對象 建立聯(lián)系戈钢。然后在添加和移除操作時,

? ? ? ? ? ? ? ? 將 KVO 的相關(guān)信息例如 observer是尔、keyPath殉了、options、context 保存為 KVOInfo 對象拟枚,并添加到 KVODelegate 對象 中對應(yīng) 的 關(guān)系哈希表 中宣渗,對應(yīng)原有的添加觀察者。

? ? ? ? ? ? 3: 在添加和移除操作的時候梨州,

? ? ? ? ? ? ? ? 利用 KVODelegate 對象 做轉(zhuǎn)發(fā)痕囱,

? ? ? ? ? ? ? ? 把真正的觀察者變?yōu)?KVODelegate 對象,

? ? ? ? ? ? ? ? 而當(dāng)被觀察者的特定屬性發(fā)生了改變(會被調(diào)用到observeValueForKeyPath:ofObject)暴匠,

? ? ? ? ? ? ? ? 再由 KVODelegate 對象分發(fā)到原有的觀察者上鞍恢。

? ? ? ? ? ? 4:為了避免被觀察者提前被釋放,

? ? ? ? ? ? ? ? 被觀察者在 dealloc 時仍然注冊著 KVO 導(dǎo)致崩潰每窖。

? ? ? ? ? ? ? ? BayMax 系統(tǒng)還利用 Method Swizzling 實現(xiàn)了自定義的 dealloc帮掉,

? ? ? ? ? ? ? ? 在系統(tǒng) dealloc 調(diào)用之前,將多余的觀察者移除掉窒典。

? 8.1.2:KVC

? ? ? KVC(Key Value Coding)鍵值編碼蟆炊,提供一種機制來間接訪問對象的屬性,而不是通過Setter/Getter方法進行訪問瀑志。

? ? ? 通常導(dǎo)致崩潰的原因不外乎鍵值設(shè)置不正確涩搓,如下:

? ? ? ? ? 1. key 不是對象的屬性

? ? ? ? ? 2. keyPath 不正確

? ? ? ? ? 3. value 為 nil,為非對象設(shè)值

? ? ? ? ? 4. key 為 nil

? ? ? 那如何防護呢劈猪,熟悉KVC機制的同學(xué)肯定清楚:runtime提供了相應(yīng)的補救措施來避免應(yīng)用崩潰昧甘,包括如下:

? ? ? ? ? ? setValue:forKey: 找不到相應(yīng)的key會調(diào)用 setValue: forUndefinedKey: 方法;

? ? ? ? ? ? valueForKey: 找不到相應(yīng)的keyPath會調(diào)用 valueForUndefinedKey: 方法战得;

? ? ? ? ? ? setValue:forKey:添加value為nil方法充边,會調(diào)用setNilValueForKey方法來避免;


? ? ? 因此常侦,針對上面崩潰的前3中場景浇冰,就可以通過分辨實現(xiàn)上述三種方法來避免贬媒,但對于key為nil的情況該如何防護呢?

? ? ? ? ? ? 這里直接告訴答案:毅然是通過熟悉的Method Swizzle來替換原有的

? ? ? ? ? ? setValue:forKey:方法肘习,

? ? ? ? ? ? 并判斷傳入的key是否為nil际乘。具體代碼如下:


圖4
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市井厌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌致讥,老刑警劉巖仅仆,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異垢袱,居然都是意外死亡墓拜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門请契,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咳榜,“玉大人,你說我怎么就攤上這事爽锥∮亢” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵氯夷,是天一觀的道長臣樱。 經(jīng)常有香客問我,道長腮考,這世上最難降的妖魔是什么雇毫? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮踩蔚,結(jié)果婚禮上棚放,老公的妹妹穿的比我還像新娘。我一直安慰自己馅闽,他們只是感情好飘蚯,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著福也,像睡著了一般孝冒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拟杉,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天庄涡,我揣著相機與錄音,去河邊找鬼搬设。 笑死穴店,一個胖子當(dāng)著我的面吹牛撕捍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播泣洞,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼忧风,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了球凰?” 一聲冷哼從身側(cè)響起狮腿,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呕诉,沒想到半個月后缘厢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡甩挫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年贴硫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伊者。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡英遭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出亦渗,到底是詐尸還是另有隱情挖诸,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布法精,位于F島的核電站税灌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏亿虽。R本人自食惡果不足惜菱涤,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望洛勉。 院中可真熱鬧粘秆,春花似錦、人聲如沸收毫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽此再。三九已至昔搂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間输拇,已是汗流浹背摘符。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逛裤。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓瘩绒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親带族。 傳聞我的和親對象是個殘疾皇子锁荔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

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