KVO的简单了解与使用

715 阅读2分钟

简介

KVO(键值监听),即 Key-Value Observing, 是Objective-C 对观察者设计模式的一种实现。它提供一种机制,当指定的对象的属性被修改后(执行了setter 或 KVC 赋值),对象就会接受到通知。

应用

当某个对象的某个属性值改变时,用KVO监听。

QQ.png

QQ.png

示例

1、模型创建 在.h中

@interface PDcar : NSObject
@property (nonatomic,assign) int num;    // 属性
@end

2、在 VC 中监听并响应属性改变

@interface ViewController ()

@property (nonatomic,strong)PDcar *myCar;    //声明了car属性

@end
- (void)viewDidLoad { 
[super viewDidLoad]; 

self.myCar = [[PDcar alloc] init]; 

//设置监听
[self.myCar addObserver:self forKeyPath:@"num" options:
NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
}

3、实现监听回调方法

// 只要object的keyPath属性发生变化,就会调用此方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
change:(NSDictionary<NSString *,id> *)change context:(void *)context{

// 判断是否为self.myCar的属性“num”:
if([keyPath isEqualToString:@"num"] && object == self.myCar) { 
    // 响应变化处理
    self.label.text = [NSString stringWithFormat:@"当前的num值为:%@",
[change valueForKey:@"new"]]; 

    //change的使用:上文注册时,枚举为2个,因此可以提取change字典中的新、旧值的这两个方法 
    NSLog(@"oldnum:%@ ----newnum:%@",[change valueForKey:@"old"],
    [change valueForKey:@"new"]); 
  }
}

4、注销监听

-(void)dealloc{
    // 移除KVO 
    [self removeObserver:self forKeyPath:@"num" context:nil];
}

注意!同一个属性不能重复removeObserver,否则会出问题。

监听数组

www.cnblogs.com/XYQ-208910/…

与Notification(通知)、代理的区别

  • notification 比 KVO 多了发送通知的一步。 两者都是一对多,但是对象之间直接的交互,notification 明显得多,需要notificationCenter 来做为中间交互。而 KVO 如我们介绍的,设置观察者->处理属性变化,至于中间通知这一环,则隐秘多了,只留一句“交由系统通知”,具体的可参照以上实现过程的剖析。

notification 的优点是,监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,例如键盘、前后台等系统通知的使用也更显灵活方便。

  • 和 delegate 一样,KVO 和 NSNotification 的作用都是类与类之间的通信。但是与 delegate 不同的是: 这两个都是负责发送接收通知,剩下的事情由系统处理,所以不用返回值;而 delegate 则需要通信的对象通过变量(代理)联系; delegate 一般是一对一,而这两个可以一对多。

  • 另外需要注意的是,由于KVO方式的注入是在运行时而不是编译时实现的,如果给定的实例没有观察者,那么 KVO 不会有任何开销,因为此时根本就没有 KVO 代码存在。但是即使没有观察者,委托和 NSNotification 还是得工作,这也是KVO此处零开销观察的优势。