iOS KVO的简单使用

KVO

什么是KVO呢?怎么使用呢?KVO(key-value-observing)是一种监听回调机制,某一个对象注册监听后,当这个对象发生了改变,就会发送一个通知给监听者,监听者的响应方法就会被唤起,从而执行回调操作。

这里先给大家说明一下它的使用方法(就三个方法,掌握了就是干货):
1.添加观察者:

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;

2.响应的方法:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context

3.移除观察者:

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

参数使用方法:

object : 被观察对象
observer: 观察对象
forKeyPath:被观察对象的属性名(添加观察者和响应方法中的forKeyPath是一一对应的)
options: 有4个值,分别是:
NSKeyValueObservingOptionNew 响应方法显示更改后的数据
NSKeyValueObservingOptionOld 响应方法显示更改前的数据
NSKeyValueObservingOptionInitial 把初始化的值提供给处理方法,一旦注册,立马就会调用一次。通常它会带有新值,而不会带有旧值。
NSKeyValueObservingOptionPrior 分2次调用。在值改变之前和值改变之后。

context: 任何类型参数

接下来我给大家举一个简单的例子,首先我们先生成一个Person类

@interface ViewController ()

/* Person */
@property (nonatomic, strong) Person *person;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //初始化Person类
    self.person = [[Person alloc] init];
    self.person.age = 0;
    
    //对person中的age属性进行KVO监听
    [self.person addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
    
    //person中age发生变化,通知响应方法被调用
    self.person.age = 2;
}

//通知的响应方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    NSLog(@"\n keyPath:%@ \n object: %@ \n change:%@ \n context:%@", keyPath, object, change, context);
}

//控制器被销毁后,移除观察者
-(void)dealloc {
    [self.person removeObserver:self forKeyPath:@"age"];
}

这里就很明显,当self.person.age = 2这一行代码执行之后,通知就会发送,响应方法就会被调用。打印的参数如下:

 keyPath:age 
 object: <Person: 0x60000000bbf0> 
 change:{
    kind = 1;
    new = 2;
    old = 0;
} 
 context:(null)

这就很简单了,不用解释了吧,哈哈哈。

以下是罗列的KVO的优缺点,大家在使用时一定要了解到:

优点:
     1.能够提供一种简单的方法实现两个对象间的同步。例如:model和view之间同步;
     2.能够对非我们创建的对象,即内部对象的状态改变作出响应,而且不需要改变内部对象(SKD对象)的实现;
     3.能够提供观察的属性的最新值以及先前值;
     4.用key paths来观察属性,因此也可以观察嵌套对象;
     5.完成了对观察对象的抽象,因为不需要额外的代码来允许观察值能够被观察
缺点:
     1.我们观察的属性必须使用strings来定义。因此在编译器不会出现警告以及检查;
     2.对属性重构将导致我们的观察代码不再可用;
     3.复杂的“IF”语句要求对象正在观察多个值。这是因为所有的观察代码通过一个方法来指向;
     4.当释放观察者时不需要移除观察者。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 简单概述下 KVO 的实现: 当你观察一个对象时,一个新的类会动态被创建。这个类继承自该对象的原本的类,并重写了被...
    迷失的昨天阅读 316评论 0 0
  • 情景 今天用到第三方的一个兼容webView与wkwebView的时候,对于IMYwebview中的属性esti...
    孤单雨凉阅读 777评论 0 1
  • 本文由我们团队的 纠结伦 童鞋撰写。 文章结构如下: Why? (为什么要用KVO) What? (KVO是什么...
    知识小集阅读 7,429评论 7 105
  • 上半年有段时间做了一个项目,项目中聊天界面用到了音频播放,涉及到进度条,当时做android时候处理的不太好,由于...
    DaZenD阅读 3,051评论 0 26
  • KVO即“键值监听”,通常需要三步: 1、添加监听对象【addObserver: forKeyPath: opti...
    碧海云天V阅读 269评论 0 1