将来跳槽用

iOS KVO的简单使用

2018-03-28  本文已影响94人  枫developer

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.当释放观察者时不需要移除观察者。
上一篇 下一篇

猜你喜欢

热点阅读