KVO解析(一) —— 基本了解

版本記錄

版本號 時間
V1.0 2017.09.13

前言

KVO具有更強大的功能,是蘋果給我們的一個回調機制,在某個對象注冊監聽者后,在被監聽的對象發生改變時,對象會發送一個通知給監聽者,以便監聽者執行回調操作。接下來幾篇就詳細的解析一下KVO。

基本基礎及原理

鍵值觀察提供了一種機制,允許將對象的更改通知給其他對象的特定屬性。 它在應用程序中的模型和控制器層之間的通信特別有用。 (在OS X中,控制器層綁定技術極大地依賴于鍵值觀察。)控制器對象通常觀察模型對象的屬性,而視圖對象通過控制器觀察模型對象的屬性。 然而,此外,模型對象可以觀察其他模型對象(通常用于確定依賴值何時改變)甚至本身(再次確定依賴值何時改變)。

您可以觀察屬性,包括簡單屬性,一對一關系和多對多關系。 許多關系的觀察者被告知所做的改變的類型以及變更涉及的對象。

一個簡單的例子說明了KVO如何在您的應用程序中有用。 假設一個Person對象與一個Account對象交互,代表該人在一家銀行的儲蓄賬戶。 個人實例可能需要了解帳戶實例的某些方面如何變化,例如余額或利率。

如果這些屬性是帳戶的公共屬性,則人員可以定期輪詢帳戶以發現更改,但這當然是低效的,并且通常是不切實際的。 更好的方法是使用KVO,類似于發生更改時收到中斷的人員。

要使用KVO,首先必須確保觀察到的對象,在這種情況下的帳戶符合KVO。 通常,如果您的對象從NSObject繼承并以通常的方式創建屬性,則對象及其屬性將自動符合KVO標準。 也可以手動執行合規性。 KVO合規性描述了自動和手動鍵值觀察之間的區別,以及如何實現兩者。

接下來,您必須使用所觀察到的實例,注冊您的觀察者實例“Person”帳戶。 Person發送一個addObserver:forKeyPath:options:context:消息給Account,每次觀察到的關鍵路徑一次,命名為觀察者。

為了從Account接收更改通知,Person實現了所有觀察者所需的observeValueForKeyPath:ofObject:change:context:方法。 任何一個已注冊的鍵值路徑發生變化的情況下,該Account將會發送消息給Person。 然后,Person可以根據更改通知采取適當的措施。

最后,當它不再需要通知,并且至少在它被釋放之前,Person實例必須通過將消息removeObserver:forKeyPath發送到Account來取消注冊。

注冊鍵值觀察描述了鍵值觀察通知的注冊,接收和取消注冊的完整生命周期。KVO的主要優點是,您不必在每次屬性更改時實施自己的方案來發送通知。 其明確的基礎架構具有框架級支持,使其易于采用 - 通常您不必為項目添加任何代碼。 此外,基礎架構已經是全功能的,這使得輕松支持單個屬性的多個觀察者以及依賴值。

與使用NSNotificationCenter的通知不同,不存在為所有觀察者提供更改通知的中心對象。 相反,當進行更改時,通知將直接發送到觀察對象。 NSObject提供了這個鍵值觀察的基礎實現,你很少需要重寫這些方法。

鍵值觀察是一種機制,可以在另一個對象的屬性更改時直接通知對象。 關鍵值觀察(或KVO)可以是應用程序凝聚力的重要因素。 它是根據模型 - 視圖 - 控制器設計模式設計的應用程序中的對象之間的通信模式。 例如,您可以使用它來將模型對象的狀態與視圖和控制器層中的對象進行同步。 通常情況下,控制器對象會觀察模型對象,視圖對象會觀察控制器對象或模型對象。

使用KVO的要求是對象必須能支持KVC機制——所有NSObject的子類都支持這個機制。

雖然UIKit框架的類通常不支持KVO,但您仍然可以在應用程序的自定義對象中實現它,包括自定義視圖。下圖就是一種KVO的原理示意圖。

使用KVO,一個對象可以觀察到另一個對象的任何屬性,包括簡單屬性,一對一關系以及多對多關系。 一個對象可以找出屬性的當前值和先前值。 許多關系的觀察者不僅被告知改變的類型,而且被告知哪些對象涉及變化。

作為通知機制,鍵值觀察與NSNotificationNSNotificationCenter課程提供的機制相似,但也有顯著差異。 不是將通知廣播到已注冊為觀察者的所有對象的中心對象,KVO通知會在發生屬性值更改時直接進行觀察對象。

再看一部分開發文檔。

Automatic key-value observing is implemented using a technique called isa-swizzling... When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class ..

翻譯過來的主要意思就是:在我們對某個對象完成監聽的注冊后,編譯器會修改監聽對象的isa指針,讓這個指針指向一個新生成的中間類。

這里說明一下isa這個指針, isa是一個指向Class類指針(專業術語是指向元類,pointer to the metaclass),用來指向類的類型,我們可以通過object_getClass方法來獲取這個值;正常來說,class方法內部的實現就是獲取這個isa指針代表的元類(metaclass),但在kvo機制中蘋果注冊監聽對象后 通過objc_allocateClassPair動態重新創建了一個新類和元類。


KVO的實現

根類NSObject提供了一個基本的鍵值觀察實現,您很少需要重寫。 因此,所有Cocoa對象本身就具有關鍵價值觀察能力。 要接收屬性的KVO通知,您必須執行以下操作:

  • 對于你想觀察的屬性,您必須確保被觀察的類是鍵值遵守。KVO合規性要求觀察對象的類別也符合KVC,并且允許屬性的自動觀察者通知或實現對屬性的手動鍵值觀察。

  • 添加一個觀察者的值可以改變的對象。 您可以通過調用addObserver:forKeyPath:options:context :來執行此操作。 觀察者只是您的應用程序中的另一個對象。

  • 在觀察對象中,實現方法observeValueForKeyPath:ofObject:change:context:。 當觀察到的對象的屬性的值發生變化時,調用此方法。


KVO是綁定的一部分(OS X)

Cocoa綁定是一種OS X技術,它允許您在模型中保留值并將應用程序的圖層同步,而無需編寫大量“膠合代碼”。通過Interface Builder檢查器,您可以在視圖的屬性和一條數據之間建立一個介于中間的連接,“綁定”它們,使得一個變化反映在另一個中。 KVO以及鍵值編碼和鍵值綁定是可可綁定功能的技術。

后記

未完,待續~~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容

  • 引言 鍵值觀察(KVO)提供了一種機制以允許對象被告知其他對象的特定屬性的更改,它對應用程序中的模型和控制器層之間...
    漸z閱讀 586評論 0 0
  • KVO編程指南 Key-Value Observing Programming Guide 1 Introduct...
    codeTao閱讀 616評論 0 0
  • 版本記錄 前言 KVO具有更強大的功能,是蘋果給我們的一個回調機制,在某個對象注冊監聽者后,在被監聽的對象發生改變...
    刀客傳奇閱讀 613評論 0 1
  • 前言 KVO(Key-Value Obsering)鍵值觀察。KVO是一種機制,該機制允許將需要被觀察的對象的指定...
    煙火_jason閱讀 549評論 0 0
  • 這一年,經歷了太多太多,多到之后的人生也許都在這一年定下了基調,想簡要回顧一下,卻又不知從何說起。 這一年收到的最...
    Adelina_520閱讀 459評論 2 2