什麼是KVO?
KVO(Key-Value Observing)鍵值觀察,是一種通過對物件的某一個屬性新增觀察者,一旦這個屬性值發生變化,就會通知當前觀察者的一種機制。
該如何使用?
1.註冊,指定被觀察者的屬性
[object addObserver:self forKeyPath:key options:NSKeyValueObservingOptionNew context:nil];
引數說明:
object:被觀察的物件
observer:觀察者物件
keyPath:被觀察物件的屬性名稱
NSKeyValueObservingOptions:有4個值
NSKeyValueObservingOptionNew 監聽它的新值
NSKeyValueObservingOptionOld 監聽它的舊值
NSKeyValueObservingOptionInitial 監聽初始化
NSKeyValueObservingOptionPrior 分2次呼叫。監聽舊值和新值
context: 可以帶入一些引數,任何型別都可以,強制轉就可以。
2.實現回撥函式
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSLog(@"keyPath---->%@ change--->%@",keyPath,change); }
引數說明:
keyPath:被觀察物件的屬性名稱
object:被觀察的物件
change:新值或者舊值
context:對應的context
3. 移除觀察
[object removeObserver:self forKeyPath:@"name"];
引數說明:
object:被觀察的物件
observer:觀察者物件
keyPath:被觀察物件的屬性名稱
寫個測試程式測試一下:
Person.h
#import <Foundation/Foundation.h> @interface Person : NSObject { @private NSString *address; } @end
Person.m
#import "Person.h" #import "Car.h" @interface Person () @property (nonatomic ,strong) NSString *name; @property (nonatomic,strong)Car *car; @end @implementation Person -(id)init { self=[super init]; if(self){ self =[super init]; self.car=[[Car alloc]init]; } return self; } @end
Car.h
#import <Foundation/Foundation.h> @interface Car : NSObject @end
Car.m
#import "Car.h" @interface Car() @property (nonatomic ,strong) NSString *brand; @end @implementation Car @end
測試程式碼:
//新增KVO觀察者 -(void)addObserver { [self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld context:@"haha"]; [self.person addObserver:self forKeyPath:@"address" options:NSKeyValueObservingOptionNew context:nil]; [self.person addObserver:self forKeyPath:@"car.brand" options:NSKeyValueObservingOptionNew context:nil]; } -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSLog(@"keyPath---->%@ change--->%@",keyPath,change); } //移除KVO觀察者 -(void)removeObserver { [self.person removeObserver:self forKeyPath:@"name"]; [self.person removeObserver:self forKeyPath:@"address"]; [self.person removeObserver:self forKeyPath:@"car.brand"]; }