当前位置: 首页 > 编程日记 > 正文

8 iOS中KVO 的本质

前言本质

Automatic key-value observing is implemented using a technique called isa-swizzling

这计划的意思就是
自动的键值观察的实现基于 isa-swizzling

原理

1.KVO是基于runtime机制实现的

2.当某个类的属性对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,

在这个派生类中重写基类中任何被观察属性的setter 方法。

派生类在被重写的setter方法内实现真正的通知机制

3.如果原类为Dog,那么生成的派生类名为NSKVONotifying_Dog

4.每个类对象中都有一个isa指针指向当前类,当一个类对象的第一次被观察,那么系统会偷偷将isa指针指向动态生成的派生类,从而在给被监控属性赋值时执行的是派生类的setter方法

5.键值观察通知依赖于NSObject 的两个方法: willChangeValueForKey: 和 didChangevlueForKey:;在一个被观察属性发生改变之前, willChangeValueForKey:一定会被调用,这就 会记录旧的值。而当改变发生后,didChangeValueForKey:会被调用,继而 observeValueForKey:ofObject:change:context: 也会被调用。

一  KVO 的使用


#import "ViewController.h"
#import "Person.h"
@interface ViewController ()@property (nonatomic,strong)Person *p1;@property (nonatomic,strong)Person *p2;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.// 监听person 类的属性值self.p1 = [[Person alloc]init];self.p1.name = @"p1_dog";self.p2 = [[Person alloc]init];self.p2.name = @"p2_dog";NSKeyValueObservingOptions val = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;[self.p1 addObserver:self forKeyPath:@"name" options:val context:nil];
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{self.p1.name = @"p1_cate";self.p2.name = @"p2_cate";}- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{NSLog(@"%@ value changed from %@",keyPath,change);
}@end

二 如何实现监听 ?

本质原因就是这两个对象的isa 指向不一样吗,主要是使用runtime 动态生成了一个派生类

1 如果未使用kvo 监听对象的时候

使用KVO 监听的话

三 代码验证


利用runtime 进行验证一下子,进入断电模式打印一下

	self.p1 = [[Person alloc]init];self.p1.name = @"p1_dog";self.p2 = [[Person alloc]init];self.p2.name = @"p2_dog";// 打印添加监听之前 setName的方法NSLog(@"监听之前%p--%p",[self.p1 methodForSelector:@selector(setName:)],[self.p1 methodForSelector:@selector(setName:)]);NSKeyValueObservingOptions val = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;[self.p1 addObserver:self forKeyPath:@"name" options:val context:nil];NSLog(@"监听之后%p--%p",[self.p1 methodForSelector:@selector(setName:)],[self.p1 methodForSelector:@selector(setName:)]);NSLog(@"end");

添加之后,setName 的实现走的是_NSSetObjectValueAndNotify 方法

四 KVO的 调用顺序

KVO 的调用顺序是:

  • 调用 willChangeValueForKey:
  • 调用原来的 setter 实现
  • 调用 didChangeValueForKey:

也就是说 didChangeValueForKey: 内部必然是调用了 observerobserveValueForKeyPath:ofObject:change:context:方法。

相关文章:

完成工作表-使用Google Spreadsheets作为数据后端

by Gilad Dayagi通过吉拉德达亚吉 完成工作表-使用Google Spreadsheets作为数据后端 (Get Sheet Done — using Google Spreadsheets as your data backend) If you want to rapidly prototype your next web apps, try using Google Spreadsheets as your data backend.如果您…

BIEE-CSS样式大全

字体属性&#xff1a;(font) 大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到&#xff0c;只要用数值就可以&#xff0c;单位&#xff1a;PX、PD 样式 {font-style: oblique;}(偏斜体) italic;(斜体) normal;(正常) 行高 {line-height: normal;}(正常) 单位&…

基于verilog的FPGA编程经验总结(XILINX ISE工具)

1.用ISE仿真的时候.所用变量一定要初始化. ISE默认初始量为"XXXXX", 而Quarters是默认为"00000"的, 其实实际上, 下到FPGA里后也是默认为0的,只是可以说ISE严谨得令人DT吧.比如说用一个累加器, result ABresult ,必须保证在某一刻A, B, result都为定值时,…

6 OC 中的isa 指针

目录 一 isa 指针 二 类对象中的superclass 一 isa 指针 isa 指针 &#xff0c;OC 中的对象都是有的 如下图所示&#xff0c;实例对象isa 指针指向 类对象&#xff0c;类对象的isa 指针指向 元类对象 二 类对象中的superclass superclass 有什么用呢&#xff1f; 比如说创…

btf-raft共识算法_了解Raft共识算法:学术文章摘要

btf-raft共识算法by Shubheksha通过Shubheksha 了解Raft共识算法&#xff1a;学术文章摘要 (Understanding the Raft consensus algorithm: an academic article summary) This post summarizes the Raft consensus algorithm presented in the paper In Search of An Underst…

iOS asset 中定义颜色,xib中便捷访问

在aseet 中定义一个颜色 这样就可以在xib 中访问颜色了&#xff0c;这样就不用重复的去输入

三种序列化方式性能比较

一下代码比较了二进制序列化、xml序列化、Protobuf序列化的运行时间&#xff0c;可是代码显得十分冗余&#xff0c;是否有大神可以指点一二&#xff0c;万分感谢 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; usi…

mac mini 装UBUNTU后没有WIFI解决办法

1、在终端中运行如下命令&#xff0c;重新安装b43相关的全部驱动和firmware: 复制代码代码如下:sudo apt-get install bcmwl-kernel-source #Broadcom 802.11 Linux STA 无线驱动源sudo apt-get install broadcom-sta-commonsudo apt-get install broadcom-sta-sourcesudo apt-…

区块链c端应用小程序_区块链如何真正起作用? 我建立了一个应用程序向您展示。...

区块链c端应用小程序by Sean Han通过肖恩韩 区块链如何真正起作用&#xff1f; 我建立了一个应用程序向您展示。 (How does blockchain really work? I built an app to show you.) According to Wikipedia, a blockchain is:根据维基百科&#xff0c;一个区块链是&#xff1…

HDU 4913 Least common multiple

/* hdu4913 Least common multiple http://acm.hdu.edu.cn/showproblem.php?pid4913 离散化 线段树 统计逆序数思想 tips: 1、线段树中一定要到处都取模&#xff0c;否则wa。。。 2、lazy是乘积的形式出现&#xff0c;不是加和*/ #include <cstdio> #include <algori…

JS ES6 实用笔记

微信小程序开发交流qq群 581478349 承接微信小程序开发。扫码加微信。 这篇博文我会一直更新。 一.导出导入的两中方式 1.export //demo1.js export const a 6 导入语法为&#xff1a; import {a} form demo1 2.export default //demo2.js export default const b 6 …

extjs editgrid增加一行

Ext.onReady(function(){ /* * EditorGridPanel的工作过程 * 1、用户点击单元格 * 2、单元格按照预设的组件显示单元格的内容并处于编辑状态 * 3、离开单元格的编辑状态 * 4、更新编辑后的内容&#xff0c;出现三角号表示已经被修改过 * 5、程序内部变化&#xff1a;将记录设置…

unity 骨骼击碎_保证击碎$ 100挑战的创新策略

unity 骨骼击碎by Glenn Gonda由Glenn Gonda 保证击碎$ 100挑战的创新策略 (A Creative Strategy Guaranteed to Crush the $100 Challenge) Before I became a software engineer, I made my living as a recording studio engineer. I have a non-traditional background an…

mac下安装libpng环境

用go写一个爬虫工具时需要使用一个go的库&#xff0c;而这个库有需要使用libpng库&#xff0c;不然编译就会提示说 png.h找不到等之类的信息&#xff0c;于是想到应该和windows一样需要安装gcc环境&#xff0c;然后让gcc里安装libpng这个库&#xff0c; 解决办法&#xff1a; 终…

linux oracle修改编码utf8

$ sqlplus /nolog SQL> connect sys/oracle as sysdba SQL> startup 如何设置ORACLE数据库的编码&#xff08;ZHS16GBK&#xff09;修改成UTF8 SQL> shutdown immediate; SQL> startup mount; SQL> alter system enable restricted session; SQL> alter sy…

Vue.js 数据绑定渲染Demo

微信小程序开发交流qq群 581478349 承接微信小程序开发。扫码加微信。 <div id"app">{{ message }} </div>var app new Vue({el: #app,data: {message: Hello Vue!} })Hello Vue!

angular搭建项目步骤_建立健康的Angular项目应采取的步骤

angular搭建项目步骤by Ashish Gaikwad通过Ashish Gaikwad 建立健康的Angular项目应采取的步骤 (Steps you should take to build a healthy Angular project) 使用Jenkins SonarQube创建您的“ Angular Fitbit” (Create your “Angular Fitbit” with Jenkins SonarQube) …

数据库的三大范式和事物

来源&#xff1a;http://blog.csdn.net/w__yi/article/details/19934319 1.1 第一范式&#xff08;1NF&#xff09;无重复的列 1.2 第二范式&#xff08;2NF&#xff09;属性完全依赖于主键 [ 消除部分子函数依赖 ] 1.3 第三范式&#xff08;3NF&#xff09;属性不依赖于其它非…

过滤器和包装器

作者&#xff1a;禅楼望月 过滤器要做的事情 请求过滤器 完成安全检查 重新格式化请求首部或体 建立请求审计或日志响应过滤器 压缩响应流 追加或修改响应流 创建一个完全不同的响应注意不能把过滤器的顺序依赖性硬编码进程序中&#xff0c;它应该由DD控制。 过滤器很像Servlet…

Missing space before value for key 'path'vue.js解决空格报错

微信小程序开发交流qq群 581478349 承接微信小程序开发。扫码加微信。 找到 webpack.base.config.js文件注释掉下面的东西&#xff01;&#xff01; module: { rules: [ /*{ test: /\.(js|vue)$/, loader: eslint-loader, enforce: "p…

现代hy-9600音响_从音响工程师到软件工程师-为什么我要学习编码

现代hy-9600音响by Kalalau Cantrell通过Kalalau Cantrell 从音响工程师到软件工程师-为什么我要学习编码 (From Sound Engineer to Software Engineer — Why I’m Learning to Code) I seriously started teaching myself to code several months ago. I say “seriously” …

微信服务号、公众号、企业号注册

转载于:https://www.cnblogs.com/zhoulaoshi/p/6536850.html

a标签onclick事件解析

微信小程序开发交流qq群 581478349 承接微信小程序开发。扫码加微信。 简单介绍<a>标签的常用点击事件的写法及作用 a href"javascript:void(0);" οnclick"js_method()" //javascript:void(0);作用是返回undefined&#xff0c;地址不发生跳转&am…

安卓版文字扫描识别软件

安卓版文字扫描识别软件 文字识别软件被越来越多的人使用&#xff0c;在使用的过程中也发现了一些问题。总结这些问题发现&#xff0c;很多人对软件能够批量识别这个问题比较关注。如果实现批量识别就可以节省时间。但是一些软件还不能实现批量识别&#xff0c;还有的软件能够做…

中级前端笔试_在短短8个月内如何获得中级前端开发人员的角色

中级前端笔试by Matthew Burfield通过马修伯菲尔德(Matthew Burfield) 在短短8个月内如何获得中级前端开发人员的角色 (How I got a mid-level front end developer role in just 8 months) Three weeks ago I landed a mid-level front-end developer role at a startup. Our…

用stm32f10x建立新的工程重要步骤

stm32f10x系列新建空的工程主要原理&#xff1a; 1.添加启动文件 不同的芯片类型的启动文件的容量是不同的&#xff0c;选择适合该芯片的容量作为启动文件。 注意&#xff1a;启动文件是汇编语言编写的&#xff0c;所以文件的后缀名为.s 2.添加时钟配置 配置文件 stm32f10x.的系…

随机生成6位图片验证码

1. [代码][C#]代码 /// <summary> /// PicHandler1 的摘要说明 /// </summary> public class PicHandler1 : IHttpHandler, IRequiresSessionState { private string mCheckNo string.Empty; protected ImgBuilder _ImgBuilder new I…

html 页面传值

微信小程序开发交流qq群 581478349 承接微信小程序开发。扫码加微信。 直接上代码&#xff0c;JS保存全局变量的三种方式。 创建一个新的JS文件&#xff0c; //quanju.js window.localStorage.JQa"JQA"; window.localStorage.setItem(JQb,JQB);//利用localStora…

node.js的开发流程_Node.js子流程:您需要了解的一切

node.js的开发流程by Samer Buna通过Samer Buna Node.js子流程&#xff1a;您需要了解的一切 (Node.js Child Processes: Everything you need to know) 如何使用spawn()&#xff0c;exec()&#xff0c;execFile()和fork() (How to use spawn(), exec(), execFile(), and fork…

对象存在性检测集中管理

在中大型业务系统中&#xff0c; 常常需要从数据库中查询某个实体对象。 在进行处理之前&#xff0c; 必须先检测该实体是否存在&#xff0c;以增强系统的健壮性。 不过&#xff0c; 检测代码充斥在主业务流程中又会大大降低业务逻辑的清晰性&#xff0c; 最好集中起来进行管理…