iOS开发之KVO

KVO:(Key-Value-Observer)键值观察者,是观察者设计模式的一种具体实现。

在我们编程中,很多时候,需要对一些对象进行监听,一旦这个对象发生变化,其他的对象就需要对其作出反应,KVO 就可以完成这项任务。

1、KVO 的触发机制与使用步骤

KVO触发机制:
一个对象(观察者),监测另一对象(被观察者)的某属性是否发生变化,若被监测的属性发生的更改,会触发观察者的一个方法(方法名固定,类似代理方法)

KVO使用步骤:
1、注册观察者(为被观察者指定观察者以及被观察属性)
2、实现回调方法
3、触发回调方法(被观察属性发生更改)
4、移除观察者

2、KVO 的基本用法

下面举一个小例子来说明 KVO 的基本用法:
1)、我们先来创建一个Person类:

#import <Foundation/Foundation.h>

@interface Person : NSObject
//  姓名
@property(nonatomic, copy) NSString *name;
@end

2)、在 ViewController.m 中创建 Person 类,并添加观察者对其监听:

- (void)viewDidLoad {
    [super viewDidLoad];
    //  初始化Person
    self.person = [Person new];
    _person.name = @"孙悟空";
    
    //  添加观察者
    [_person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:(__bridge void *)self];

    //  添加改变person值得手势
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
    [self.view addGestureRecognizer:tap];
}

3)、实现 tapAction 方法:

- (void)tapAction:(UITapGestureRecognizer *)sender {
    _person.name = @"猪八戒";
}

4)、实现 KVO 方法:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
    //  keyPath 是观察的属性
    NSLog(@"keyPath = %@", keyPath);
    //  object 被观察的对象
    NSLog(@"%@", object);
    //  change 新旧值
    NSLog(@"change = %@", change);
    
    //  对其变化进行判定
    if ([change[NSKeyValueChangeNotificationIsPriorKey] boolValue]) {
        NSLog(@"值改变之前");
    } else {
        NSLog(@"值改变之后");
    }
    
    //  context 的作用就是传值
    ViewController *vc = (__bridge ViewController *)context;
    vc.view.backgroundColor = [UIColor greenColor];
}

通过以上方法就可以实现:触摸屏幕,改变person.name的值,从而调用 KVO,使得背景屏幕变成绿色。

在MVC中,KVO的使用场景通常是,M与C通信,M发生变化通知C。其中M是被观察者,C是观察者。

另外需要注意一点:观察者销毁之前,移除观察者,否则会出现程序异常(给已经销毁的对象发送消息)

推荐阅读更多精彩内容