kvo概述

  kvo,全称Key-Value Observing,它提供了一种方法,当对象某个属性发生改变时,允许监听该属性值变化的对象可以接受到通知,然后通过kvo的方法响应一些操作。

kvo实现原理

  kvo是如何实现通知对象的呢,其实这是通过Objective-C强大的runtime运行时机制实现的。当你第一次观察某个对象时,runtime会创建一个新的继承被监听类的子类。在这个新的类中,它会重写所有被观察的key,然后将对象的isa指针指向新创建的类。所以对象神奇的变成了新的子类的实例。这些被重写的方法中添加了调用通知观察者的方法的代码。当一个对象的一个属性改变时,会触发setKey方法,但这个方法被重写了,并且在内部添加了发送通知机制。

kvo实现原理验证实验

  1.我们新建一个Single View Application工程。然后新建一个Person类和一个Dog类。

  2.在Person.h中增加一个属性age。

#import <Foundation/Foundation.h>

@interface Person : NSObject//新增一个age属性
@property (nonatomic,assign) int age;

@end

  3.在Dog.m中添加kvo监听方法observeValueForKeyPath:ofObject:change:context:

#import "Dog.h"

@implementation Dog
//kvo监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    NSLog(@"%@监听到了%@对象的%@属性的值改变了:%@",self ,object ,keyPath ,change);
}

@end

  4.在ViewController.m文件中添加如下代码

#import "ViewController.h"
#import "Person.h"
#import "Dog.h"

@interface ViewController ()

@property (nonatomic, strong)Person *person;
@property (nonatomic, strong)Dog *dog;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.person = [[Person alloc] init];
    self.dog = [[Dog alloc] init];

    self.person.age = ;

    //self.dog 监听self.person的age属性
    [self.person addObserver:self.dog forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];

}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    self.person.age = ;
}

  从上面的代码可以看出,视图加载成功后,Dog就可以监听Person的age属性的变化了。

  5.我们运行程序,然后点击空白屏幕,就会看到如下输出,说明我们的确实已经能够使用kvo监听属性变化了。

  6.然后我们通过打断点的方式,会看到在调用addObserver:forKeyPath:options:context:方法前后Person所属类是不同的。

    添加观察器之前:

  添加观察器之后:

  通过前后对比,我们发现当person对象被监听后,系统在运行时动态创建了一个继承自Person的子类NSKVONOtifying_Person类。然后KVO会在这个派生类中,重写基类中任何被观察属性的setter方法,在setter方法中实现真正的通知机制。

- (void)setAge:(int)age

{

[super setAge:age];

[监听者 observeValueForKeyPath:@"age"  ofObject:self  change:@{}  context:nil];

}

  KVO是一个很强大的工具,有时候过于强大了,尤其是有了自动触发通知机制。现在我们知道了它的工作原理,知道使用它会在运行时创建一个新的类,所以性能会有一定影响,因此除非非要监听某个属性值的变化时候才使用它。这些知识或许能帮助你更好地使用它,或在它出错时更方便调试。

KVO的内部实现原理的更多相关文章

  1. KVO内部实现原理

    KVO的原理: 只要给一个对象注册一个监听, 那么在运行时, 系统就会自动给该对象生成一个子类对象, (格式如:NSKVONotifying_className), 并且重写自动生成的子类对象的被监听 ...

  2. Mininet的内部实现原理简介

    原文发表在我的博客主页,转载请注明出处. 前言 之前模拟仿真网络一直用的是Mininet,包括写了一些关于Mininet安装,和真实网络相连接,Mininet简历拓扑的博客,但是大多数都是局限于具体步 ...

  3. Angular单页应用&AngularJS内部实现原理

    回顾 自定义指令 登录后获取登录信息session 首先在登录验证的时候保存一个user 在学生管理页面中运用ajax调用获取到登录的用户信息 对注销按钮添加点击事件:调用ajax在表现层给user赋 ...

  4. 8. 理解ZooKeeper的内部工作原理

    到目前为止,我们已经讨论了ZooKeeper服务的基础知识,并详细了解了数据模型及其属性. 我们也熟悉了ZooKeeper 监视(watch)的概念,监视就是在ZooKeeper命名空间中的znode ...

  5. Redis有序集内部实现原理分析(二)

    Redis技术交流群481804090 Redis:https://github.com/zwjlpeng/Redis_Deep_Read 本篇博文紧随上篇Redis有序集内部实现原理分析,在这篇博文 ...

  6. (译)KVO的内部实现

    09年的一篇文章,比较深入地阐述了KVO的内部实现.   KVO是实现Cocoa Bindings的基础,它提供了一种方法,当某个属性改变时,相应的objects会被通知到.在其他语言中,这种观察者模 ...

  7. [转](译)KVO的内部实现

    转载自:http://www.cocoachina.com/applenews/devnews/2014/0107/7667.html   09年的一篇文章,比较深入地阐述了KVO的内部实现.   K ...

  8. Apache Lucene评分机制的内部工作原理

    Apache Lucene评分机制的内部工作原理' 第5章

  9. Flask源码分析二:路由内部实现原理

    前言 Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. 上次了解了 ...

随机推荐

  1. 【c++】读写txt

    #include<iostrea> #include<fstream> int main() { ofstream fout;// 创建一个ofstream对象 fout.op ...

  2. libCEF总结02字符串

    libCEF 的 CefString.cef_string_t 在 Windows 下均表示一个 16 位的 Unicode 字符串,它们的使用请参考下面的代码 {//wchar_t* ==> ...

  3. VC++多工程项目

    目录 第1章 VC++6.0    1 1.1 设置依赖关系    1 1.2 编译顺序    2 1.3 自动连接    3 1.4 静态库    3 1.4.1 嵌入    3 1.4.2 替换  ...

  4. 使用TCP/IP的套接字(Socket)进行通信

    http://www.cnblogs.com/mengdd/archive/2013/03/10/2952616.html 使用TCP/IP的套接字(Socket)进行通信 套接字Socket的引入 ...

  5. android GC内存回收小析

    由于时间问题,简单的谈谈自己的理解. 大家都知道,在android开发中,不需要自己去管理,有垃圾回收机制会自动帮我们去回收 没有被引用到的对象. 那垃圾回收机制到底是怎样的呢?下面列出本人的一些理解 ...

  6. js,jquery判断某一节点是否存在

    前两天工作时遇到一问题,就是模块A显示时,B是一种样式,模块A删除,B是另一种样式.记录下判断节点存在的方法. 先写下html <!doctype html> <html> & ...

  7. CSDN中的Bug

    简述 在用CSDN的过程中,发现了许许多多的Bug.之前没有做记录,直接反馈给客服了,有时没图说得不太清楚,现在不都追求有图有真相么O(∩_∩)O~,所以在此记录一下. 作为程序员的一份子,Bug对我 ...

  8. Pinyin4Net

    .net使用的汉字转拼音库.Pinyin4Net 是直接从 Pinyin4J 翻译过来的,很多代码甚至是直接copy的. 用法与pinyin4j完全相同,具体请查阅pinyin4j文档. —— 查看更 ...

  9. JSON生成c#类代码小工具(转)

    原文地址: http://www.cnblogs.com/tianqiq/archive/2015/03/02/4309791.html

  10. 转:Struts2<s:iterator value="" var="lst">中var的使用和一些标签的使用体会

    比如<s:iterator value="pmOperateList" var="lst"> <!-- iterator加上var 等价于重新 ...