04从0搭建一个KVO

之前章节

01.OC实例对象的本质
02.OC有几种对象
03.对象的isasuperclass

网上很多文章讲解KVO的实现原理,但没过多久可能就忘了,这篇文章带你从苹果开发者的角度来实现KVO监听的技术,假设你现在是一名苹果开发人员,没错,我们现在就是一名苹果开发人员,遇到了一个问题,如下图


遇到了个问题

当age改变的时候,希望能调用personAgeChanged方法,这时我们会想要怎么去实现该功能呢?
最简单的,我们可以使用代理或通知模式来告诉外面,代理的话,假设有几个属性要监听的就要写很多个代理方法,太麻烦了,这里我们采用通知订阅者模式,那么通知模式通常有个通知管理中心,我们创建一个通知中心类,叫KZKVONotifictionCenter,KZ是个人前缀可忽略,如下图:


通知管理中心

分别有添加监听、移除监听、即将改变值、已经改变值方法,但如果我们要使用这个监听中心,其实也挺麻烦的,能否更加面向对象一点呢,这时我们就可以考虑使用oc的分类方法,同样创建一个NSObject+KVO分类,它的代码如下:


NSObject分类方法

有了分类方法,那么我们就可以这样子调用

分类添加监听的调用代码

哇,真的方便多了,那么我们的分类方法里面实现是怎样的呢?让我们来看看

分类添加通知的实现

大家可以看到,添加监听向监听中心添加,然后把自己的isa指向自己的子类KZKVONotifying_Person,为啥要指向自己的子类,我们先来看看子类KZKVONotifying_Person的代码

KZKVONotifying_Person子类代码

原来在子类中,重写了setAge,可以看到子类的setAge分别调用了kz_willChangeValueForKey和kz_didChangeValueForKey,这俩个方法,其实是让监听中心记录下改变前和改变后的值,存储起来,然后告知监听者

监听中心的实现

如果我们的监听者如果有实现kz_observeValueForKeyPath…这个方法,那么就可以监听到age改变时的通知了,如下图完整调用代码

完整调用

是不是很简单,这个模式主要是针对键值的监听,key-value-observer,那么我们就叫它KVO吧~

上面模拟了苹果对KVO的简单粗暴版实现,那么我们如何证明系统也是这样子实现的呢,首先证明的是调用addObserver这个方法后,isa指向改变的问题,可以看下图,指向前和指向后的isa

添加监听前isa的指向
添加监听后isa的指向

这里可能你会奇怪,KVONotifying_Person这个类没定义是从哪里来的,答案是苹果利用运行时,动态创建子类,继承了Person,这样子更加方便开发,神不知鬼不觉的实现了该技术,不用我们自己去创建子类实现。至于更换isa有啥用,我们在前面的章节讲过,isa指向了子类后,会去查找子类的方法列表,子类重写了对age的监听,这时调用了setAge,其实isa会去KVONotifying_Person调用setAge,如图

isa指向图
细节补充
  • 子类的set方法最终会调用_NSSet类型ValueAndNotify函数,如_NSSetIntValueAndNotify,为什么要使用该函数呢?本人的想法是函数里面调用了xxxxx代码,都是同一份,所以不需要每次都动态生成
  • 既然isa指向改了,为什么使用[Person class]方法还是返回Person,不应该返回KVONotifying_Person么,答案是KVONotifying_Person也重写了class方法,返回了Person,原因是不想让开发关注太多东西,不需要知道是怎么实现的,不止class,还重写了dealloc和_isKVOA等方法
  • 直接修改成员变量不会触发KVO,只有经过set方法的才会触发,KVC经过set方法,会触发
  • 记得移除kvo,有没有不用移除更好的方式?可以去搜一下KVOController库看看

本文部分知识来自李明杰的教程,感谢观看~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容

  • KVO的全称是Key-Value Observing,俗称“键值监听”,可以用于监听某个对象属性值的改变 一、KV...
    伶俐ll阅读 333评论 0 1
  • KVO简介 KVO全称为(Key-Value-Observing),俗称兼职兼听,用于监听摸个对象属性值的改变,由...
    ForstDragon阅读 493评论 0 0
  • 问题 iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?) 如何手动触发KVO ? 首先需要了解KVO...
    hjltony阅读 579评论 0 2
  • 一、KVO 问题 iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?) 如何手动触发KVO? 1. K...
    CoderJRHuo阅读 597评论 0 0
  • iOS底层原理总结 - 探寻KVO本质 对小码哥底层班视频学习的总结与记录。 面试题:iOS用什么方式实现对一个对...
    爱吃兔兔的胡萝卜吖阅读 292评论 0 1