解剖iOS中KVO的原理

        为什么还要讲KVO的原理呢,如果想了解KVO原理,上网一查,可以搜出一大堆文章,不是更好?以前我也是上网一查,大概知道了怎么回事,但是呢,过一段时间,你肯定忘了,不知道你是否有同感,原因?

1.  你用零碎的时间学习零碎的知识,不能形成有意识的系统知识,这样只是一场过客,时间一长,你还得去重新查找,浪费时间和精力不说,你觉的有意思吗?

2. 网上的文章说的不全,比如说,说了对象,但是没有说容器;说了基本使用,没有说底层的实现等

3. 没有相关代码来佐证等

        而本篇文章试图从最简单的用法说起,由浅入深,覆盖对象和容器,底层机制

一.    一般基本的使用,新建一个对象Animal,在头文件中加一个name的属性


图1

同时在ViewControler中创建Animal的对象,同时监听该对象的name属性


图2

结果:点击vc,得到结果如下:


图3

这是一个对象完整的使用基本KVO的流程

说明:

        NSKeyValueObservingOptionNew              // 返回新值

        NSKeyValueObservingOptionOld                // 返回旧值

        NSKeyValueObservingOptionInitial             // 注册的时候就会发一次通知,改变的时候也会发通知

        NSKeyValueObservingOptionPrior             // 改变之前发一次,改变之后发一次

二. 上面是name改变值都会发送通知,但是现在我只要满足特定条件才发送通知,另外情况都不需要发送通知,怎么做呢?

    iOS提供了2种模式给我们选择,一种是 默认的自动模式,一种是手动模式

    2.1 手动模式

          在Animal的m文件中重载实现automaticallyNotifiesOberversOfName函数,返回NO即可,结果是没有返回值

图4

        然后我想要只在touchesBegan函数中才改变值才通知,另外情况都不需要通知,如下


图5

        为什么需要willChange和didChange 2个函数呢?因为NSKeyValueObservingOptions的选项有返回旧值和新值,所以willChange对应返回旧值,didChange返回新值,也就是说这2个是成双成对出现的

三. 属性依赖,如果在Animal对象里有另外一个对象,然后要监听那个对象的属性呢,新增一个cat对象,增加age的属性,在Animal里增加一个Cat对象,同时在ViewController里监听Cat对象的age属性


图5

另外一种情况是:如果在cat对象中有很多属性,这样在监听的时候是不是要写很多监听的代码呢,是否有简单的方法来统一监听所有的属性呢??

eg:

    [self.a addObserver:self forKeyPath:@"cat.age" options:NSKeyValueObservingOptionNew context:nil];

    [self.a addObserver:self forKeyPath:@"cat.kind" options:NSKeyValueObservingOptionNew context:nil];

    ....

iOS提供了一个方法来返回指定的属性容器,达到只要监听对象的目的

eg: 在ViewController中

[self.a addObserver:self forKeyPath:@"cat" options:NSKeyValueObservingOptionNew context:nil];

相应的在Animal的m文件中重载keyPathsForValuesAffectingValueForKey函数


四. 如果我要观察的是容器呢,比如NSMutableArray呢,我在Animal头文件中增加一个NSMutableArray的属性,在ViewController中进行addObject操作


图6


图7

运行发现,像array里增加值,并不能发送通知,为什么??

结论:KVO监听的是属性的set方法,不是对象的变量,而addObject方法明显不是set方法,所以不会触发通知

如果NSMutableArray的addObject方法还不能证明的话,那么再通过一个例子来证明

在Animal头文件中声明一个name的变量


图8

在ViewController中监听name属性


图9

运行后发现,没有发送通知

五. 底层实现

    5.1 当调用addObserver函数的时候,系统运行时自动帮你把Animal类替换为了 NSKVONotifying_Animal类,同时重写了set方法,当我们查看addObserver函数的时候,可以看到该函数在NSObject分类下@interfaceNSObject(NSKeyValueObserverRegistration)

这里大家要理清一个概念:方法跟类有关系,成员变量跟对象有关系

   5.2 新增一个NSObject的一个分类来替换系统的分类


图10

疑问:为什么要添加setName方法?自定义的子类没有该方法?是的,没有该方法,子类继承于父类,父类有,但是子类没有

六. 容器实现监听,使用KVC技术

iOS提供了mutableArrayValueForKey等多个KVC的方法来生成一个KVO的array,来实现addObject方法的监听

但是,我发现count不是数组的属性,不能进行监听修改,以上就是本文的内容,有不当之处欢迎指出。

七. 课后作业

      7.1 不知道大家有没发现,对于change返回的kind值,对象和容器是不一样的,一个是1,一个是2,那么是否还有第三个,第四个... 呢,这个kind代表什么意思呢?


对象


容器

    7.2. 关于在图10中的keyMethod方法,里面分别去调用父类的setName,同时调用observer函数,为什么不直接调用子类的setName方法??

关于这些问题,我会在下期的KVC详解中解答

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

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,294评论 8 265
  • 问题 iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?) 如何手动触发KVO ? 首先需要了解KVO...
    hjltony阅读 574评论 0 2
  • KVC KVC定义 KVC(Key-value coding)键值编码,就是指iOS的开发中,可以允许开发者通过K...
    暮年古稀ZC阅读 2,127评论 2 9
  • 该文章属于刘小壮原创,转载请注明:刘小壮[https://www.jianshu.com/u/2de707c93d...
    刘小壮阅读 48,236评论 35 227
  • 昨晚读书会很晚才结束,和男人商量着今天去扫墓的。 今早一早就醒来,做饭喊男人吃饭,男人很沉默。我也不去编织,做...
    张连娜阅读 203评论 1 1