iOS消息传递之KVO

2017-05-06  本文已影响102人  西叶lv

  KVO简介:键值观察,是基于键值编码(KVC)的一种观察模式。 是iOS中常用的一种消息传递机制。
  对接模式:发送者和接收者的关系为一对多的关系,一个发送者可以有多个接收者。
  使用键值观察需要被观察对象编写符合KVC标准的存取方法,使用步骤分为以下三步:

[ObjectOfObserved addObserver:observerObject forKeyPath:@"example" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

KVO注册方法参数:

options枚举:
1、NSKeyValueObservingOptionNew:该枚举值保证KVO监听属性的新内容,当属性内容变化时,KVO会记录属性的新内容,这样KVO回调方法中的参数change字典中包括改变后的值,可以通过KVO的监听回调方法获取到属性的新内容
2、NSKeyValueObservingOptionOld:该枚举值保证KVO监听属性的原内容,当属性内容变化时,KVO会记录属性的原内容,这样KVO回调方法中的参数change字典包括改变前的值,可以通过KVO的监听回调方法获取到属性的原内容
3、NSKeyValueObservingOptionInitial: 注册后立刻触发KVO通知,添加该枚举后,即使属性值没有变化,也会调用KVO回调方法
4、NSKeyValueObservingOptionPrior:值改变前是否也要通知(这个key决定了是否在改变前改变后通知两次)

如何设置context:
可以参考这篇文章Key-Value Observing中《正确的上下文声明》部分;以及这篇文章 kvo/gcd中关于context指针的赋值

  第二步:在观察者的.m实现文件中定义KVO的回调方法

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

该方法是系统提供的观察者实现键值观察方法,作为观察者,需要实现这个方法。当被观察的被观察属性发生变化时(这里的变化是指赋值操作,只要给属性赋值就会调用,就算赋相同的内容,也会调用),会自动调用这个方法。

KVO回调方法中参数:

KVO回调方法操作:

* 获取被监听者对象```
    监听者对象类型 *变量名 = object;
* 获取被监听者内容已变时的属性对象```
属性对象类型 * new = [change objectForKey:NSKeyValueChangeNewKey];

  第三步:在观察者的.m文件中的dealloc方法中移除观察者

- (void)dealloc {
    // 调用移除观察者的方法:- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
    [ObjectOfObserved removeObserver:Observer forKeyPath:@"example"];
}

KVO移除方法参数:

注:如果忘记解除移除监察,会导致资源泄露

  拓展一: KVO手动设置
 KVO模型中,有两种通知观察者的方式,自动通知和手动通知。一般我们都用系统自动通知,文章开篇介绍的就是KVO自动通知。
 KVO手动通知的设置出了完成自动通知的三个步骤,需要在被观察者的.m实现文件中重写类方法:

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

返回NO时,告诉系统使用KVO手动通知;返回YES时,使用KVO自动通知,默认为YES;
参数key为NSString类型,被监听的keyPath , 用来区分不同的KVO监听。
另外,在当被监听的属性发生变化时,需要调用属性值将要改变的方法和属性值已经改变方法

// 手动通知在需要改变example变量的地方,使用

[self willChangeValueForKey:@"example"];

self.example = @"我是被监听的属性,字符串类型的";

[self didChangeValueForKey:@"example"];


自动通知在需要改变example变量的地方,使用KVC设置属性内容的方法,而不是仅仅使用简单赋值。

[self setValue:@"我是被监听的属性,字符串类型的" forKey:@"example"];

手动改变属性内容时,我们需要在3个地方改变属性的内容值,即:请求结束时、连接出错误,线程被cancel。请在对应的方法代码中加入手动变值的语句。

  拓展二: KVC简单介绍
可以参看这篇文章:iOS开发技巧系列---详解KVC(我告诉你KVC的一切)

参考文章

上一篇 下一篇

猜你喜欢

热点阅读