KVO
2016-01-12 16:33
323 查看
KVO简单介绍与实现
Key Value Observing, 顾名思义就是一种observer 模式用于监听property的变化,KVO跟NSNotification有很多相似的地方, 用addObserver:forKeyPath:options:context:去start observer, 用removeObserver:forKeyPath:context去stop observer, 回调就是observeValueForKeyPath:ofObject:change:context:。KVO 的实现也依赖于 Objective-C 强大的 Runtime 。
简单概述下 KVO 的实现:
当你观察一个对象时,一个新的类会动态被创建。这个类继承自该对象的原本的类,并重写了被观察属性的 setter 方法。自然,重写的 setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象值的更改。最后把这个对象的 isa 指针 ( isa 指针告诉 Runtime 系统这个对象的类是什么 ) 指向这个新创建的子类,对象就神奇的变成了新创建的子类的实例。
原来,这个中间类,继承自原本的那个类。不仅如此,Apple 还重写了 -class 方法,企图欺骗我们这个类没有变,就是原本那个类。更具体的信息,去跑一下 Mike Ash 的那篇文章里的代码就能明白,这里就不再重复。
[code]下面是从另外一个博客搞过来的示例代码:
[code]@interface StockData : NSObject { NSString * stockName; float price; } @end @implementation StockData @end - (void)viewDidLoad { [super viewDidLoad]; stockForKVO = [[StockData alloc] init]; [stockForKVO setValue:@"searph" forKey:@"stockName"]; [stockForKVO setValue:@"10.0" forKey:@"price"]; [stockForKVO addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL]; myLabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 30 )]; myLabel.textColor = [UIColor redColor]; myLabel.text = [stockForKVO valueForKey:@"price"]; [self.view addSubview:myLabel]; UIButton * b = [UIButton buttonWithType:UIButtonTypeRoundedRect]; b.frame = CGRectMake(0, 0, 100, 30); [b addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:b]; } -(void) buttonAction { [stockForKVO setValue:@"20.0" forKey:@"price"]; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if([keyPath isEqualToString:@"price"]) { myLabel.text = [stockForKVO valueForKey:@"price"]; } } - (void)dealloc { [stockForKVO removeObserver:self forKeyPath:@"price"]; }
相关文章推荐
- SuperMap GIS 8C sp1三点制图功能改进
- HttpClient和HttpURLConnection知识收集
- Cocos2D结合CoreGraphics实现RPG人物中空黑洞吸入效果
- mssql的update :from语法
- boost::asio::io_service和io_service::work和boost::thread_group配合使用
- .bashrc 文件中增加头文件路径和库文路径
- 从HDFS拷贝一个表到系统目录生成CSV
- 华为机试——整数倒序输出,剔除重复数据
- 如何用Python脚本自动SVN Update
- ios tableview 插入删除
- 运行程序提示access violation at address的解决方法
- APP测试基本流程
- TestNG中如何执行测试
- 软件危机和软件生存期
- JVM垃圾回收与性能调优总结 JVM调优的几种策略
- 使用Gitlab一键安装包后的日常备份恢复与迁移
- Ubuntu Android开发环境配置
- Linux的基础知识之用户、组合权限(一)
- input怎么限制只能输入数字?
- block使用详解