一、使用方法
1、注冊
NSKeyValueObservingOptionNew:change字典包括改變后的值
NSKeyValueObservingOptionOld: change字典包括改變前的值
NSKeyValueObservingOptionInitial:注冊后立刻觸發(fā)KVO通知
NSKeyValueObservingOptionPrior:值改變前是否也要通知(這個key決定了是否在改變前改變后通知兩次)
//監(jiān)聽姓名屬性的變化
[person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
2、實現回調方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject: (id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"name"]) {
NSLog(@"Name is changed new = %@",[change objectForKey:NSKeyValueChangeNewKey]);
}else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
3、移除通知
- (void)dealloc
{
[self.person removeObserver:self forKeyPath:@"name" context:nil];
}
二、經典的KVO使用場景(model與view同步)
- (void)testKVO
{
Person *person = [Person new];
self.person = person;
[person addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
}
//實現回調
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"age"]) {
NSString *old = [change objectForKey:NSKeyValueChangeOldKey];
NSString *nw = [change objectForKey:NSKeyValueChangeNewKey];
// self.oldValueLB.text = old;
self.valueLB.text = nw;
NSLog(@"%@ %@",old,nw);
}else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];;
}
}
//移除
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.person removeObserver:self forKeyPath:@"age" context:nil];
}
- (IBAction)button:(id)sender {
self.person.age = [NSString stringWithFormat:@"%u",arc4random()%100];//取余
}
三、手動設置KVO通知
- (void)setAge:(NSString *)age
{
if ([age integerValue] < 18) {
NSLog(@"未成年");
}
[self willChangeValueForKey:age];
_age = age;
[self didChangeValueForKey:age];
}
//不自動
+ (BOOL)automaticallyNotifiesObserversOfAge
{
return NO;
}