今天终于开始写我的第一个简书,哈哈,目前自己iOS开发也两年了,也是时候分享一下经验了。好吧,废话不多说,开始第一个技术分享:
什么是KVO?
KVO是Key-Value-Observing的缩写,通过KVO这种机制对象可以通过它得到其他对象的某个属性的变更通知。这种机制在MVC模式下显得更为重要,KVO可以让视图对象经过控制器观察模型对象的变更从而做出更新等操作。
KVO这一机制是基于NSKeyValueObserving协议的,Cocoa通过这个协议为所有遵循协议的对象提供了自动观察属性变化的能力。在NSObject中已经为我们实现了这一协议,所以我们不必去实现这个协议。
为什么要使用KVO?
有的朋友可能会有疑问,为什么要使用KVO呢?KVO能实现的我使用Setter方法同样能实现啊。其实不然KVO存在还是有它的价值的,那么接下来我们看看一下KVO的独特价值吧:
1.我们创建一两个setter方法感觉没什么,但是如果要观察的属性非常多,那么还能一一重写setter方法来实现吗?想必大家心里已有了答案,但是利用KVO则能很好的解决上述问题。
2.我们自定义的类是很容易改写setter方法的,但是如果你是用一个已经编译好了的类库时要监控其中一个属性时怎么办?难道还要去重写setter方法?如果使用KVO则很轻松解决问题。
3.使用KVO能够方便的记录变化前的值和变化后的值,不适用KVO你还要自己来解决这些问题。
4.KVO让你的代码看起来更加简洁清晰易于维护。
KVO的使用
那么我们怎么来使用kvo呢,其实只要记住KVO的三部曲就好了
1>注册.指定被观察者的属性 (也就是说你要观察谁?观察谁的哪个属性的变化?)
2>实现回调方法 (当你要监听的属性的值被改变了,那么就要在回调的方法里面做你想要做的事情,例如更新UI什么的)
3>移除观察者 (增加观察与取消观察是成对出现的,所以需要在最后的时候,移除观察者)
代码示例(以下就是用kvo做的一个小小的Demo)
首先我们要新建一个数据模型(以数据模型作为被观察者)
KvoModel.h文件
#import@interface KvoModel : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
#import "ViewController.h"
#import "KvoModel.h"
@interface ViewController ()
@property (weak, nonatomic) UILabel *labelText;
@property (strong, nonatomic) KvoModel *model;
@end
@implementation ViewController
//移除观察
- (void)dealloc {
[self.model removeObserver:self forKeyPath:@"age"];
}
- (void)buttonPressed {
self.model.age += 5;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
KvoModel *model = [[KvoModel alloc]init];
self.model = model;
[self.model setValue:@"小崔" forKey:@"name"];
[self.model setValue:@10 forKey:@"age"];
//创建控件
[self setUpSubView];
//注册,指定被观察者的属性,
[self.model addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
self.labelText.text = [NSString stringWithFormat:@"%ld岁",(long)self.model.age];
}
//实现回调方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
self.labelText.text = [NSString stringWithFormat:@"%@ %ld岁", self.model.name,self.model.age];
NSLog(@"keyPath ====%@ id =======%@ dict =========%@ ", keyPath, object, change);
}
//创建按钮和label
- (void)setUpSubView {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(120, 200, 100, 35)];
[btn setBackgroundColor:[UIColor lightGrayColor]];
[btn setTitle:@"增加5岁" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(buttonPressed)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
UILabel *labelText = [[UILabel alloc]initWithFrame:CGRectMake(30, 50, 300, 30)];
self.labelText = labelText;
self.labelText.text = [NSString stringWithFormat:@"%@现在的年龄是: %ld", self.model.name, (long)self.model.age];
[self.view addSubview:self.labelText];
}
@end
好了,不足之处,希望大家多多指教!
LuckCui
网友评论