项目地址:探索KVO(使用->设计)
网上KVO的文章基本上到处都是,这里自己就总结了下,KVO很强大,基本上KVO就是Objective-C对观察者模式的实现,可以观察某个属性的变化,针对变化通知响应的观察者做出反应。
###总结从:基本使用->实现是一个时钟->了解观察者模式->了解KVO实现原理->利用runtime自己设计KVO替换掉官方API更加深入的了解它。
基本使用
设计一个Model:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// // LastDays.h // KVO // // Created by LastDays on 16/4/4. // Copyright © 2016年 LastDays. All rights reserved. // #import <Foundation/Foundation.h> @interface LastDays : NSObject @property(nonatomic,strong) NSString *name; @end |
设计Observer(观察者)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#import "LastdaysObserver.h" @implementation LastdaysObserver -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{ NSLog(@"old = %@",[change objectForKey:NSKeyValueChangeOldKey]); NSLog(@"old = %@",[change objectForKey:NSKeyValueChangeNewKey]); NSLog(@"context:%@",context); } @end |
就是重写
1 2 3 4 |
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context |
进入测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
// // ViewController.m // KVO // // Created by LastDays on 16/4/4. // Copyright © 2016年 LastDays. All rights reserved. // #import "ViewController.h" #import "LastDays.h" #import "LastdaysObserver.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self test]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(void)test{ LastdaysObserver *lastdaysObserver = [[LastdaysObserver alloc] init]; LastDays *lastdays = [[LastDays alloc] init]; lastdays.name = @"ok"; [lastdays addObserver:lastdaysObserver forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:(void*)self]; lastdays.name = @"name"; [lastdays removeObserver:lastdaysObserver forKeyPath:@"name"]; } @end |
在这里我们使用一下方法添加观察者
1 2 3 4 |
[lastdays addObserver:lastdaysObserver forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:(void*)self]; |
查看打印结果:
1 2 3 |
2016-04-04 11:25:04.231 KVO[4046:379396] old = ok 2016-04-04 11:25:04.232 KVO[4046:379396] old = name 2016-04-04 11:25:04.232 KVO[4046:379396] context:<ViewController: 0x7faa0ae34da0> |
KVV(键值验证)
可以用来校验数据:
通过一下方法:
1 |
- (BOOL)validateValue:(inout id *)ioValue forKey:(NSString *)inKey error:(out NSError **)outError; |
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
-(void)test{ LastdaysObserver *lastdaysObserver = [[LastdaysObserver alloc] init]; LastDays *lastdays = [[LastDays alloc] init]; NSString *name =@"lastdays"; lastdays.name = name; //添加观察者 [lastdays addObserver:lastdaysObserver forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:(void*)self]; if ([lastdays validateValue:&name forKey:@"name" error:nil]) { NSLog(@"数据不为空"); }else{ NSLog(@"数据为空"); } lastdays.name = @"Lastdays"; //移除观察者观察的对应属性 [lastdays removeObserver:lastdaysObserver forKeyPath:@"name"]; } |
结果:
1 2 3 4 |
2016-04-04 12:00:05.157 KVO[4099:398267] 数据不为空 2016-04-04 12:00:05.159 KVO[4099:398267] old = lastdays 2016-04-04 12:00: |