KVO機制的應用

KVO即Key-value observing,鍵值觀察機制。文檔裏面對於KVO的介紹的第一句話是:

    “Key-value observing is a mechanism that enables an object to be notified directly when a property of another object changes.”

告訴我們,KVO是一種機制,這種機制可以使一個對象在其它某個對象的屬性發生改變時被直接通知到。我覺得這句話卻很好的詮釋了KVO的作用。在OC中,每個對象都是獨立的,但是我們的項目卻需要信息的傳遞,而且app的交互很頻繁也很重要,當某個東西(對象)發生改變時,另一些對象怎麼能夠迅速直接的做出反應,就可以使用到KVO。我覺得它和通知機制、委託機制一樣,都是爲了更好的在對象之間進行溝通。

    首先,添加觀察者:

[self.buttonA addObserver:self forKeyPath:@"center" options:(NSKeyValueObservingOptionPrior|NSKeyValueObservingOptionNew) context:nil];
方法的調用者是被觀察者,參數anObserver是觀察者,也就是在self.buttonA的屬性發生改變時,self做出反應。keyPath是被觀察的屬性,並非任何屬性發生改變都會通知觀察者。option是一個枚舉:

enum {
   NSKeyValueObservingOptionNew = 0x01,
   NSKeyValueObservingOptionOld = 0x02,
   NSKeyValueObservingOptionInitial = 0x04,
   NSKeyValueObservingOptionPrior = 0x08
};
typedef NSUInteger NSKeyValueObservingOptions;
這個枚舉值可以疊加選擇,會影響到通知觀察者的信息類型。

    然後,在被觀察者的制定屬性發生改變時,觀察者會調用特定方法,類似回調:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    NSLog(@"%@",change);
    if ([keyPath isEqualToString:@"center"]) {
        CGPoint centerA = self.buttonA.center;

        self.buttonB.center = CGPointMake(centerA.x+distance.x, centerA.y+distance.y);;
    }
}
上面option參數的選項就是影響這裏的change這個字典的值。選擇了NSKeyValueObservingOptionNew 和 NSKeyValueObservingOptionOld 會在change裏面加入改變時新的值和之前舊的值;添加了NSKeyValueObservingOptionInitial 會在被觀察者初始化制定屬性的時候調用KVO的回調方法,否則不會;而 NSKeyValueObservingOptionPrior 會使得上面的回調方法在每次改變的時候調用兩次,在改變前一次、後一次,類似於UIViewController的viewWillAppear和viewDidAppear這兩種對應狀態。

因爲是系統回調,參數是系統給的,如果想加入某個特定的變量用於回調後的處理,可以給context賦值。這個機制在很多地方可以看到。上面添加觀察者時的方法我們傳入自定義的變量context,回調時系統會把這個context傳給後面的回調方法。只是在使用時轉成原本的類類型,比如:

NSString * str = (__bridge_transfer id)context;


  只有兩個方法,使用簡單,不過change字典具有多個鍵值:

NSString *const NSKeyValueChangeKindKey;
NSString *const NSKeyValueChangeNewKey;
NSString *const NSKeyValueChangeOldKey;
NSString *const NSKeyValueChangeIndexesKey;
NSString *const NSKeyValueChangeNotificationIsPriorKey;
運用好這些鍵值,通過它們給的信息,應該可以達到一些簡單而奇妙的效果。可以省去一些冗雜的代碼,以後繼續研究。簡單的使用就這些了。


KVO的簡單例子:github地址


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章