KVO 其原理探究
什么是KVO ?
KVO这是Key-Value Observing,它提供了一种机制,指定的对象的属性被改动后,则对象就会接受到通知。
简单的说就是每次指定的被观察的对象的属性被改动后。KVO就会自己主动通知对应的观察者了。
KVO简单样例
新建一个Person类:
#import <Foundation/Foundation.h> @interface Person : NSObject
@property (nonatomic, assign) int age;
@end
在控制器的ViewDidLoad方法里注冊KVO监听,并改变键值。
#import "ViewController.h"
#import "Person.h" @interface ViewController ()
@property (nonatomic, strong) Person *p;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; Person *p = [[Person alloc] init];
p.age = 20; //注冊观察者
[p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; p.age = 30;
self.p = p;
} /**
* 当监控的某个属性的值改变了就会调用
*
* @param keyPath 属性名(哪个属性改了?)
* @param object 哪个对象的属性被改了?
* @param change 属性的改动情况(属性原来的值、属性最新的值)
* @param context void * == id
*/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
NSLog(@"%@对象的%@属性改变了。由旧值%@改变为新值%@", object, keyPath, change[@"old"], change[@"new"]);
} - (void)dealloc {
//移除KVO监听
[self.p removeObserver:self forKeyPath:@"age"];
} @end
打印结果为:
2015-03-17 13:38:19.635 KVOTest[2001:60b] <Person: 0x15e5cf90>对象的age属性改变了,由旧值20改变为新值30
什么是isa ?
苹果官方是这样介绍isa的:
Every object is connected to the run-time system through its isa instance variable, inherited from the NSObject class. isa identifies the object's class; it points to a structure that's compiled from the class
definition. Through isa, an object can find whatever information it needs at runtime such as its place in the inheritance hierarchy, the size and structure of its instance variables, and the location of the method implementations it can perform in response
to messages.
通过一个实例对象的isa。我们能够找到这个对象的全部信息,如继承架构,实例变量的size和结构,响应消息机制相应的方法入口地址。
KVO前后的isa变化
变量p在KVO监听之前的isa,是Person类,例如以下:
在注冊KVO监听之后的isa,是NSKVONotifying_Person类。例如以下:
结论
可见。在addObserver:forKeyPath:options:context:之后。对象p的isa变为了NSKVONotifying_Person。
所以,依据上面的isa介绍,响应setAge的方法,实际上是对象p的isa即NSKVONotifying_Person类的setAge方法,并非原Person类的setAge方法。
能够大胆想象,NSKVONotifying_Person类是Person类的子类,在NSKVONotifying_Person类内部,重写了setAge方法。而且在setAge方法里让监听器调用了observeValueForKeyPath:ofObject:change:context:方法。
那么,NSKVONotifying_Person是怎么产生的呢?简单的说,是由runtime产生的。
兴许文章将介绍objective-c的runtime机制。
个人原创,欢迎转载,转载请注明出处:http://blog.csdn.net/iosHot
版权声明:本文博客原创文章。博客,未经同意,不得转载。
KVO 其原理探究的更多相关文章
- iOS KVO的原理
KVO(Key Value Observing),是观察者模式在Foundation中的实现. KVO的原理 简而言之就是: 1.当一个object有观察者时,动态创建这个object的类 ...
- KVO-基本使用方法-底层原理探究-自定义KVO-对容器类的监听
书读百变,其义自见! 将KVO形式以代码实现呈现,通俗易懂,更容易掌握 :GitHub -链接如果失效请自动搜索:https://github.com/henusjj/KVO_base 代码中有详 ...
- [原] KVM 虚拟化原理探究(1)— overview
KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...
- [原] KVM 虚拟化原理探究 —— 目录
KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...
- [原] KVM 虚拟化原理探究(6)— 块设备IO虚拟化
KVM 虚拟化原理探究(6)- 块设备IO虚拟化 标签(空格分隔): KVM [toc] 块设备IO虚拟化简介 上一篇文章讲到了网络IO虚拟化,作为另外一个重要的虚拟化资源,块设备IO的虚拟化也是同样 ...
- [原] KVM 虚拟化原理探究(5)— 网络IO虚拟化
KVM 虚拟化原理探究(5)- 网络IO虚拟化 标签(空格分隔): KVM IO 虚拟化简介 前面的文章介绍了KVM的启动过程,CPU虚拟化,内存虚拟化原理.作为一个完整的风诺依曼计算机系统,必然有输 ...
- [原] KVM 虚拟化原理探究(4)— 内存虚拟化
KVM 虚拟化原理探究(4)- 内存虚拟化 标签(空格分隔): KVM 内存虚拟化简介 前一章介绍了CPU虚拟化的内容,这一章介绍一下KVM的内存虚拟化原理.可以说内存是除了CPU外最重要的组件,Gu ...
- [原] KVM 虚拟化原理探究(3)— CPU 虚拟化
KVM 虚拟化原理探究(3)- CPU 虚拟化 标签(空格分隔): KVM [TOC] CPU 虚拟化简介 上一篇文章笼统的介绍了一个虚拟机的诞生过程,从demo中也可以看到,运行一个虚拟机再也不需要 ...
- [原] KVM 虚拟化原理探究(2)— QEMU启动过程
KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...
随机推荐
- 教你pomeloclient包libpomelo增加cocos2d-x 3.0工程(Windows、Android、IOS平台)
Windows平台 操作系统:Windows7(64-bit) VS版本号:2013 Cocos2d-x版本号:3.0 project路径:E:\cocos2d-prj\ 1.从github下载lib ...
- 世纪互联、微软Azure与无穷小微积分
今年9月25日,世纪互联正式开通微软Azure商用服务,有感. 我是世纪互联创业历程的见证人(之中的一个),现在看到世纪互联推出微软Azure公有云的商用服务,心 ...
- hdu 4107当卡段树
其核心思想是记录最大的节点值和最低值,假设max<p要么min>=p时间,在节点只变化add值,不要子树遍历:否则,就往子树递归. #include<iostream> #in ...
- ASP.NET Core MVC Hello World
ASP.NET Core 现在ASP.NET Core还在不断成长.更新中,说不定到了明天又换了个模样,就如同一个小孩,从蹒跚学步,到奔向未来. 所以我们可以相应的去理解更新中所发生的变化,包容它.呵 ...
- 【python下使用OpenCV实现计算机视觉读书笔记4】保存摄像头视频
读取摄像头内容,然后保存一段十秒钟的视频. import cv2 cameraCapture = cv2.VideoCapture(0) fps = 30 # an assumption size = ...
- WEB网站性能优化
最近做了一个WEB现场.幸运的是,一开始.但后来越来越慢,特别是在调试模式,,这肯定是我们的代码有问题.但是即使业务不是非常复杂的也非常慢,我们就想当然的觉得我们的代码没问题,可最后证明还是我们的代码 ...
- 王立平--include在Android应用
它包括一个布局和布局 1.在layout确定activity_other.xml布局 2.代码中的包括例如以下: <LinearLayout xmlns:android="http:/ ...
- gitLab添加ssh key
电脑新装了一台虚拟机,想要和gitLab建立一个安全的ssh连接,步骤如下 1.本机生成ssh key 系统环境:Linux 使用root用户登录,执行命令:ssh-keygen -t rsa -C ...
- #Windows Phone:在HTML5专案中,如何从Javascript传送字串到C#的APP端
原文:#Windows Phone:在HTML5专案中,如何从Javascript传送字串到C#的APP端 #Windows Phone:在HTML5专案中,如何从Javascript传送字串到C#的 ...
- 下的生产环境was重新启动不同意,怎么做?
前一段时间上线.遇到一个jndi问题,它是如何是个问题?它是在测试环境中的原始没有问题,在生产环境中,您无法连接生产数据库,然后发现问题,那是,ibm工具生成在测试环境中自己主动的连接jndi资源文件 ...