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_ ...
随机推荐
- (转)SWT的CheckBoxTreeViewer的相关用法
最近在项目中需要用到遍历某个目录下所有文件,并按照树形结构展示,同时还需要提供对树形菜单的选择展开等操作.在eclipse中提供了CheckboxTreeViewer组件来满足所需要的功能 下面是需要 ...
- POJ 2411
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9614 Accepted: 5548 ...
- Mac 登录界面多了一个其它账户删除
原因分析: 在安装一些软件时会自己主动启用root账户,可是在安装完毕后没有关闭root账户,这样就造成系统以为用户要使用root账户,所以在登录界面出现了一个"其它"账户 解决方 ...
- pygame写的弹力球
这是pygame写的弹力球 运行效果: ======================================================== 代码部分: ================= ...
- windows phone 7 通过麦克风录音,并且播放
原文:windows phone 7 通过麦克风录音,并且播放 //模拟XNA的框架(凡是在wp7中应用xna的都必须先模拟此类) public class XNAAsyncDispatcher : ...
- Oracle JDBC版本区别(转)
oracle\product\11.2.0\dbhome_1\jdbc\lib ojdbc5.jar ojdbc5dms.jar ojdbc5dms_g.jar ojdbc5_g.jar ojdbc6 ...
- 《深入理解mybatis原理》 Mybatis初始化机制具体解释
对于不论什么框架而言.在使用前都要进行一系列的初始化,MyBatis也不例外. 本章将通过下面几点具体介绍MyBatis的初始化过程. 1.MyBatis的初始化做了什么 2. MyBatis基于XM ...
- UML 之 序列图和协作图
序列图(Sequence Diagram) 亦称为时序图或循序图,是一种UML行为图.它通过描写叙述对象之间发送消息的时间顺序显示多个对象之间的动态协作.它能够表示用例的行为顺序,当运行一个用 ...
- Visual Studio Tips: How to change project namespace
/* Author: Jiangong SUN */ If you want to modify a project's namespace and its physical container na ...
- malloc功能具体解释
一.原型:extern void *malloc(unsigned int num_bytes); 头文件:#include <malloc.h> 或 #include <alloc ...