ios kvo 簡介

在一個複雜的,有狀態的系統中,當一個對象的狀態發生改變,如何通知系統,並對狀態改變作出相應的行爲是必需考慮的一個問題,在iOS中爲這類問題提供了4種解決方法: 

1. NSNotifiactaion和NSNotificationCenter:通知中心 
2. Delegates:代理, 
3. Callback:回調, 
4. KVO(Key-Value Observing):鍵值觀察 

這篇文章就來講說經過KVO通知系統狀態發生改變的用法。 

KVO是什麼? 
KVO是Object-C中定義的一個通知機制,其定義了一種對象間監控對方狀態的改變,並作出反應的機制。對象能夠爲本身的屬性註冊觀察者,當這個屬性的值發生了改變,系統會對這些註冊的觀察者作出通知。其用途十分普遍,比方說,你的下載進度條是根據下載百分比決定的,那麼,能夠經過觀察下載百分比的改變,刷新進度條的樣式,來直觀的反應下載進度等等。 

KVO的用法 
根據上面的描述,一個KVO的用法主要就涉及3個部分: 

1.爲對象的屬性註冊觀察者:對象經過調用下面這個方法爲屬性添加觀察者 
html

Object-c代碼  收藏代碼app

  1. - (void)addObserver:(NSObject *)observer  spa

  2.          forKeyPath:(NSString *)keyPath  代理

  3.             options:(NSKeyValueObservingOptions)options  server

  4.             context:(void *)context  htm

            

  • observer: 觀察者對象. 其必須實現方法observeValueForKeyPath:ofObject:change:context:.對象

  • keyPath: 被觀察的屬性,其不能爲nil.blog

  • options: 設定通知觀察者時傳遞的屬性值,是傳改變前的呢,仍是改變後的,具體的設定能夠這兒:https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html#//apple_ref/doc/c_ref/NSKeyValueObservingOptions,一般設置爲NSKeyValueObservingOptionNew。生命週期

  • context: 一些其餘的須要傳遞給觀察者的上下文信息,一般設置爲nil作用域



2.觀察者接收通知,並作出處理:觀察者經過實現下面的方法,完成對屬性改變的響應: 

Object-c代碼  收藏代碼

  1. - (void)observeValueForKeyPath:(NSString *)keyPath  

  2.                       ofObject:(id)object  

  3.                         change:(NSDictionary *)change  

  4.                        context:(void *)context  



  • keyPath: 被觀察的屬性,其不能爲nil.

  • object: 被觀察者的對象.

  • change: 屬性值,根據上面提到的Options設置,給出對應的屬性值

  • context: 上面傳遞的context對象。

                
                  
3.清除觀察者:對象經過下面這個方法移除觀察者: 

Object-c代碼  收藏代碼

  1. - (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath  



4. 注意事項: 
使用KVO消息傳遞機制有兩個要求:(1)觀察者必須知道被觀察對象,即在同一做用域。(2)觀察者還須要知道被觀察對象的生命週期,由於在銷燬發送者對象以前,須要取消觀察者的註冊。 
另外:若是計劃在Core Data對象上使用KVO,須要知道這跟通常的KVO使用方法有點不一樣。還必須結合Core Data的故障機制(faulting mechanism),一旦core data出現了故障,它將會觸發其屬性對應的觀察者(即便這些屬性值沒有發生改變)。 

5. 一些好的實踐 

  • (1)當一個觀察者觀察多個對象的相同屬性(即不一樣Object,可是KeyPath相同),可經過設定靜態的Context變量來區分不一樣的通知。

  • (2)使用NSStringFromSelector(@selector(method))來獲取KeyPath,而不是直接經過NSString寫屬性名,這樣編譯器能夠幫助發現屬性名中的Typo。

  • (3)經過方法:+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key,經過一個Key觀察多個屬性值的改變。



參考文章:http://ningandjiao.iteye.com/blog/2009729

相關文章
相關標籤/搜索