KVO 深入底層探索和遇到的常見錯(cuò)誤(一)

序言

前幾天公交車上看了一篇百度大神的關(guān)于 KVO 探索的博客瘾晃。我實(shí)地驗(yàn)證了一下子贷痪,也遇到了好多問題,一番各種查閱資料之后蹦误,決定總結(jié)分享一下劫拢,供各位看官指點(diǎn)哈~

KVO 的原理

下面的原理仔細(xì)品嘗喔~多讀幾遍就可以理解了,當(dāng)然理解不了就按我說的來點(diǎn) KVO 的代碼强胰,最后腫能理解
PS:突然發(fā)現(xiàn)簡(jiǎn)書的 markdown 語法有點(diǎn)少舱沧,比如我想在對(duì)下面的 object 加粗時(shí)候,就找不到相應(yīng)的解決方法??
1.當(dāng)一個(gè) object(對(duì)象) 有觀察者時(shí)候偶洋,動(dòng)態(tài)創(chuàng)建這個(gè) object(對(duì)象) 的類的子類 2.對(duì)于每個(gè)被觀察的 property(屬性)熟吏,重寫其 setter 方法 3.在重寫的 setter 方法中調(diào)用 -willChangeValueForKey: 和 -didChangeValueForKey: 通知觀察者 4.當(dāng)一個(gè) property(屬性) 沒有觀察者時(shí),刪除重寫的方法 5.當(dāng)沒有 observer(觀察者) 觀察任何一個(gè) property(屬性) 時(shí)玄窝,刪除動(dòng)態(tài)創(chuàng)建的子類

Demo 驗(yàn)證

Demo 簡(jiǎn)單到要死牵寺,覺著扔一張圖就看的明白,比廢話一大堆簡(jiǎn)單多了恩脂,有時(shí)候看文字是件晦澀的事情缸剪,還得一個(gè)字一個(gè)字的理解,所以此處扔圖??东亦,有想看 Demo 的 點(diǎn)我穿越

Demo

接下來看看 KVO 是怎么動(dòng)態(tài)創(chuàng)建子類的:
斷點(diǎn)1—>代碼和 Log 日志


斷點(diǎn)1-代碼
斷點(diǎn)1-Log

對(duì)比上述2張圖杏节,我們?cè)跀帱c(diǎn)1處唬渗,在控制臺(tái)分別使用- classobject_getClass() 打印person對(duì)象的類和真實(shí)的類,下面的斷點(diǎn)2和斷點(diǎn)3都按此方法打印 Log日志奋渔。

斷點(diǎn)2—>代碼和 Log 日志


斷點(diǎn)2-代碼
斷點(diǎn)2-Log

斷點(diǎn)3—>代碼和 Log 日志


斷點(diǎn)3-代碼
斷點(diǎn)3-Log

瞧~镊逝,斷點(diǎn)2的 Log 日志信息突然冒出了一個(gè)
NSKVONotifying_HQMPerson,這是什么鬼嫉鲸。撑蒜。。
我們知道為一個(gè)對(duì)象addObsever時(shí)候玄渗,也就是被觀察時(shí)座菠,
framework使用runtime動(dòng)態(tài)創(chuàng)建了一個(gè)HQMPerson類的子類NSKVONotifying_HQMPerson,而為了不讓外部知道這一行為藤树,
NSKVONotifying_HQMPerson重寫了-class方法返回之前的類浴滴,所以通過-class方法查看的類沒有變化,但是通過object_getClass()方式就會(huì)暴露出來發(fā)生了何種變化岁钓,因?yàn)檫@個(gè)object_getClass()返回的是這個(gè)對(duì)象的isa指針升略,isa指針指向的一定是這個(gè)對(duì)象所屬的類。如下圖:

isa 指向 xx

常見錯(cuò)誤

?.錯(cuò)誤1-remove觀察者
錯(cuò)誤1

造成該崩潰信息的代碼片段如下:

崩潰信息的代碼片段

上述代碼是對(duì) person 這個(gè)對(duì)象添加了監(jiān)聽屡限,而removeObserver方法卻是移除的self品嚣,顯然這是一個(gè)很低級(jí)的錯(cuò)誤。

解決方法: 觀察誰钧大,誰就應(yīng)該移除也就是偷窺誰翰撑,誰就發(fā)毛,所以就該跑

?.錯(cuò)誤2-屬性的值修改了的信息收到了啊央,但是并沒有處理

錯(cuò)誤2

其實(shí)這個(gè)很簡(jiǎn)單就是你addObserver了眶诈,
但是方法-observeValueForKeyPath:ofObject:change:context:卻沒有實(shí)現(xiàn),這個(gè)算是最低級(jí)的了??劣挫。。东帅。

解決方法:
PS:只要你注冊(cè)了 KVO压固,這個(gè)方法就必須實(shí)現(xiàn)

?.錯(cuò)誤3-添加和移除時(shí)候,context上下文不一致
錯(cuò)誤3

代碼片段如下:


context上下文不一致

解決方法:
一般來說context都傳nil

?.錯(cuò)誤4-致命性
錯(cuò)誤4

說實(shí)話遇到這個(gè)錯(cuò)誤靠闭,我還是真不知道從何入手(皆因?qū)?KVO 的理解不夠深)帐我,先看出現(xiàn)這種崩潰的原始代碼:

原始代碼片段

只要運(yùn)行,程序就會(huì)爽快的崩潰愧膀。拦键。¢萘埽看下我的注釋芬为,然后在對(duì)比一下崩潰日志信息(HQMPerson 類的實(shí)例被釋放了萄金,但是 KVO 中還有關(guān)于他的注冊(cè)信息)。
實(shí)際上媚朦,只要你明白 KVO 的知識(shí):在添加觀察者的時(shí)候氧敢,觀察者對(duì)象與被觀察的屬性所屬的對(duì)象都不會(huì)被retain,然而在這些對(duì)象被釋放后询张,相關(guān)的監(jiān)聽信息卻還存在孙乖,(ARC環(huán)境下)KVO做的處理是直接讓程序崩潰。

解決方法:
既然明白了這一點(diǎn)份氧,我們就知道如何修改了(ARC 環(huán)境下)唯袄,如下修改:

修改后代碼片段

關(guān)于 KVO 的觸發(fā)方式-自動(dòng)和手動(dòng),以及更深的底層探索待續(xù)喔蜗帜。恋拷。。會(huì)出 xxx(二) 呢(這部分得參考 apple 的官方文檔钮糖,英文有壓力??)

PS:碼一篇文章難梅掠,碼一篇好文好好難。馬丹店归,本來打算每周要寫一篇的甭管是多是少阎抒。哦。消痛。且叁。對(duì)了,馬丹...是個(gè)人名吶??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秩伞,一起剝皮案震驚了整個(gè)濱河市逞带,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纱新,老刑警劉巖展氓,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異脸爱,居然都是意外死亡遇汞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門簿废,熙熙樓的掌柜王于貴愁眉苦臉地迎上來空入,“玉大人,你說我怎么就攤上這事族檬⊥嵊” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵单料,是天一觀的道長(zhǎng)埋凯。 經(jīng)常有香客問我点楼,道長(zhǎng),這世上最難降的妖魔是什么递鹉? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任盟步,我火速辦了婚禮,結(jié)果婚禮上躏结,老公的妹妹穿的比我還像新娘却盘。我一直安慰自己,他們只是感情好媳拴,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布黄橘。 她就那樣靜靜地躺著,像睡著了一般屈溉。 火紅的嫁衣襯著肌膚如雪塞关。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天子巾,我揣著相機(jī)與錄音帆赢,去河邊找鬼。 笑死线梗,一個(gè)胖子當(dāng)著我的面吹牛椰于,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播仪搔,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼瘾婿,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了烤咧?” 一聲冷哼從身側(cè)響起偏陪,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎煮嫌,沒想到半個(gè)月后笛谦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昌阿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年饥脑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宝泵。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡好啰,死狀恐怖轩娶,靈堂內(nèi)的尸體忽然破棺而出儿奶,到底是詐尸還是另有隱情,我是刑警寧澤鳄抒,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布闯捎,位于F島的核電站椰弊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏瓤鼻。R本人自食惡果不足惜秉版,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茬祷。 院中可真熱鬧清焕,春花似錦、人聲如沸祭犯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沃粗。三九已至粥惧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間最盅,已是汗流浹背突雪。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涡贱,地道東北人咏删。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像盼产,于是被迫代替她去往敵國和親饵婆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉戏售,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,692評(píng)論 0 9
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,860評(píng)論 25 707
  • 本文代碼下載地址 一:kvo簡(jiǎn)介 Objective-C 中的鍵(key)-值(value)觀察(KVO)并不是什...
    雷鳴1010閱讀 413評(píng)論 0 0
  • 【下一章】西游殤( 57 )終相見 我剛寫西游殤的時(shí)候侨核,寫“神佛無道,欺騙眾生灌灾,我要逆天改命搓译!”結(jié)果當(dāng)晚我的電腦硬...
    傅人閱讀 1,069評(píng)論 31 26
  • 昨天些己,終于順利通過了我的研究生畢業(yè)論文答辯,至此嘿般,總算可以舒一口氣段标。 早上八點(diǎn)多從家出發(fā),兒子非哭著追到了公交站炉奴,...
    心有歡喜過生活閱讀 518評(píng)論 4 4