版本記錄
版本號 | 時間 |
---|---|
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,一個對象可以觀察到另一個對象的任何屬性,包括簡單屬性,一對一關系以及多對多關系。 一個對象可以找出屬性的當前值和先前值。 許多關系的觀察者不僅被告知改變的類型,而且被告知哪些對象涉及變化。
作為通知機制,鍵值觀察與NSNotification
和NSNotificationCenter
課程提供的機制相似,但也有顯著差異。 不是將通知廣播到已注冊為觀察者的所有對象的中心對象,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以及鍵值編碼和鍵值綁定是可可綁定功能的技術。
后記
未完,待續~~~