觀察者模式---KVO介紹

KVO:

      key  value  observer,它提供一種當指定的對象屬性被修改之後,則其觀察者會接收到通知的機制。也就是說:被指定的觀察對象的屬性被修改之後,KVO就會自動通知相應的觀察者了。這也是一種設計模式,用於兩個類之間的解耦合,尤其是業務邏輯和試圖控制器之間的解耦;

    self.p1 = [[Person alloc]init];
    self.p1.name = @"111";
    /*
     - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
     
     1 觀察者,負責處理監聽事件的對象
     2 觀察的屬性
     3 觀察的選項
     *NSKeyValueObservingOptions
     NSKeyValueObservingOptionNew = 0x01,    新值
     NSKeyValueObservingOptionOld = 0x02,    舊值
     NSKeyValueObservingOptionInitial        初始值
     NSKeyValueObservingOptionPrior          之前的值
     4 上下文
     */
    [self.p1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
    //self.p1.name = @"123";

必須實現方法

//這個方法是NSObject的,任何對象都可以作爲觀察者
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    NSLog(@"監聽到了%@的%@屬性發生了改變", object, keyPath);
    NSLog(@"%@", change);
}

 

KVO的實現原理:

         KVO是基於Runtime機制實現的,當某個類的屬性對象第一次被觀察時,系統會在運行期動態的創建該類的派生類,在這個派生類中重寫基類中任何被觀察屬性的setter方法;

例子:

原生類爲Person,那麼在運行期runtime會生成一個派生類:NSKVONotifying_person,繼承自person類,每個類對象都有一個isa指針指向當前類,當一個類對象第一次被觀察時,那麼系統會將isa指針指向動態生成的這個派生類,從而在給被監控的屬性賦值時執行的是派生類的setter方法。KVO依賴於NSObject的兩個方法:

  1> willChangeValueForKey      在一個被觀察的屬性改變之前調用,記住這個值。

  2> didChangeValueForKey       在被觀察的屬性之後調用,纔會調用observerValueForkey

解釋:當person的name屬性改變時,person對象的isa指針會指向NSKVONotifying_person,

-(void)setName:(NSString *)name
{
    //這兩個方法的底層會調用-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(id *)change context:(void *)context
    [self willChangeValueForKey:@""];
    [self didChangeValueForKey:@" "];
}

 

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