KVO&KVC

一 KVO

a) 介紹:Objective-C 中的鍵(key)-值(value)觀察(KVO)來源于設計模式中的觀察者模式,其基本思想就是:一個目標對象管理所有依賴于它的觀察者對象,并在它自身的狀態改變時主動通知觀察者對象。這個主動通知通常是通過調用各觀察者對象所提供的接口方法來實現的。觀察者模式較完美地將目標對象與觀察者對象解耦。在Objective-C 中有兩種使用鍵值觀察的方式:手動或自動,此外還支持注冊依賴鍵(即一個鍵依賴于其他鍵,其他鍵的變化也會作用到該鍵)。KVO是基于KVC實現的

b) 實現機制:

                 i.           當某個類的對象第一次被觀察時,系統就會在運行期動態地創建該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter 方法。

                ii.           派生類在被重寫的setter 方法實現真正的通知機制,就如前面手動實現鍵值觀察那樣。這么做是基于設置屬性會調用setter 方法,而通過重寫就獲得了KVO 需要的通知機制。當然前提是要通過遵循KVO 的屬性設置方式來變更屬性值,如果僅是直接修改屬性對應的成員變量,是無法實現KVO 的。

               iii.           同時派生類還重寫了class 方法以“欺騙”外部調用者它就是起初的那個類。然后系統將這個對象的isa 指針指向這個新誕生的派生類,因此這個對象就成為該派生類的對象了,因而在該對象上對setter 的調用就會調用重寫的setter,從而激活鍵值通知機制。此外,派生類還重寫了dealloc 方法來釋放資源。

c) 運用KVO

                 i.           注冊需要觀察的對象的屬性addObserver:forKeyPath:options:context:

                ii.           實現observeValueForKeyPath:ofObject:change:context:方法,這個方法當觀察的屬性變化時會自動調用

               iii.           在dealloc中移除KVO監聽:removeObserver:forKeyPath:context:

二 KVC

a) 介紹:kvc,鍵值編碼,是一個非正式的協議,觀察者模式的一種實現,它提供一種機制來間接訪問對象的屬性。直接訪問對象是通過調用訪問器的方法實現,而kvc不需要調用訪問器的設置和獲取方法,可以直接訪問對象的屬性,從而簡化我們的代碼,也可以用來修改系統控件內部屬性。最常用的場景就是字典轉模型

b) 用法:

                 i.           kvc通過鍵值對的方式對屬性設置:- (void)setValue:(id)value forKey:(NSString *)key; 

                ii.           kvc通過鍵值對的方式獲取對象屬性,相當于getter方法:- (id)valueForKey:(NSString *)key; 

               iii.           key找不到時,異常處理:- (void)setValue:(id)value forUndefinedKey:(NSString *)key;

              iv.           字典轉模型:setValuesForKeysWithDictionary

c) 賦值原理:

                 i.           去模型中查找有沒有setter方法,就直接調用這個setter方法,給模型這個屬性賦值

                ii.           如果找不到set方法,接著就會去尋找有沒有這個屬性,如果有,就直接訪問屬性賦值

               iii.           如果找不到屬性,接著又會去尋找成員變量,直接給成員變量賦值,再找不到就報異常

三 通知

a) 介紹:通知中心(NSNotificationCenter), 是IOS程序內部的一種消息廣播機制, 通過它可以完成不同對象之間的通信。如果我們想把消息從A傳遞到B, 那么通知中心的兩端就是發送者A和接收者(也就是觀察者)B, 兩者通過通知中心就可以完成通信。通知中心與代理模式類似, 但是兩者不同的是, 代理模式的每個對象只能添加一個代理, 而通過NSNotificationCenter可以實現一對多的通信, 通知的發布者可以添加多個觀察者。

b) 通知(NSNotification)的三個屬性:name、object、userInfo

c) 通知中心對于通知的操作有3步:

                 i.           通知的發布:- (void)postNotification:(NSNotification *)notification;由A把數據傳出去,發送通知

                ii.           通知的監聽:-(void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString*)aNameobject:(id)anObject; 注冊B的接收到消息方法

               iii.           通知的移除:- (void)removeObserver:(id)observer;在接收消息方法的對象中的dealloc中記得移除通知,否則會崩潰

四 KVO、通知、delegate的區別

a) 代理需要定義代碼很多,定義協議、實現協議方法等。通知不需要編寫多少代碼,實現簡單。

b) 代理是1對1傳值,通知是1對多傳值

c) 代理效率快,通知效率低

d) 代理控制流程可跟蹤,并且可識別,通知的工作以及流程難以跟蹤查看流程

e) 代理能夠接收到協議方法的返回值,通知發出后,觀察者方法不能返回數據到發送者。

f) KVO的語法比較通知更簡潔

g) KVO監聽某個類,通用一個接收方法,使用key做接收到的屬性判斷,而通知可以實現多個接收通知的方法

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容