KVO原理及監聽數組數量發生變化

kvo作用

KVO俗稱鍵值監聽,它提供一種機制,當指定的對象的屬性被修改後,則對象就會接收到通知。就是每次指定的被觀察的對象的屬性被修改後,KVO就會自動通知想要的觀察者。

使用步驟:

步驟一 

給對象添加監聽者

首先創建一個person類

@interface Person :NSObject

@property(nonatomic,copy) NSString *name;

@end



//在viewcontroller擴展中添加一個屬性

@property(nonatomic,strong) Person *person;


//並給該屬性初始化對象,並給屬性添加kvo監聽

self.person = [Person new];
[self.person addObserver:self forKeyPath:@"name"options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];

具體參數說明:

  1. observer:觀察者
  2.  forkeyPath參數是一個鍵值對中的鍵,唯一標示符綁定值。
  3. options:

             NSKeyValueObservingOptionNew:change字典包括改變後的值 

             NSKeyValueObservingOptionOld:   change字典包括改變前的值 

            NSKeyValueObservingOptionInitial: 註冊後立刻觸發KVO通知 

            NSKeyValueObservingOptionPrior:  值改變前是否也要通知

  4.     context:上下文,這個會傳遞到訂閱者的函數中,用來區分消息,所以應當是不同的。

 步驟二

如果修改了person的name的值就會觸發下面方法

//需要在這裏實現監聽後要做的操作

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

步驟三

刪除指定Key路徑的監聽器:

在- (void)dealloc;方法中移除監聽

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

- (void)removeObserver:(NSObject *)observer     forKeyPath:(NSString *)keyPath  context:(void *)context

 

 kvo原理

 主要用到了運行時(runtime)

當某個類的對象第一次被觀察時,會通過運行時動態地創建對應於該類的一個派生類,在這個派生類中系統會重寫父類中被觀察屬性的setter方法。然後根據options中的值來確定觸發哪些方法,下面會觸發改變前和改變後的方法。

-(void)setName:(NSString *)name{

    [self willChangeValueForKey:@"name"];//會在值即將發生變化時發送通知
    _name = name;
    [self didChangeVauleForKey:@"name"]; //會在值已經發生變化時發送通知

}

 automaticallyNotifiesObserversForKey該方法用於是否自動觸發kvo,返回no要手動觸發,


+(BOOL)automaticallyNotifiesObserversForKey:(NSString *)key{

    if([key isEqualToString:@"name"]){
        return NO;
    }

    return [super automaticallyNotifiesObserversForKey:key];

}

應用

商城購物車中都有一個全選按鈕,如果每個商品都一一勾選後,那麼全選按鈕就會被自動選中。如果其中一個商品沒有選中,然後全選按鈕不會被選中。

這裏需要監聽加入購物車數組對象。


@interface ViewController ()

//下單數據源
@property(nonatomic,strong) NSMutableArray *pendingDataSource;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //監聽pendingDataSource對象是否發生變化
    [self addObserver:self forKeyPath:@"pendingDataSource" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

}

-(void)addAction{
   [[self mutableArrayValueForKey:@"pendingDataSource"] addObject:person];
}

demo地址https://github.com/lijsrn/KVODemo

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