KVO简介

在 Cocoa 的模型-视图-控制器 (Model-view-controller)架构里,控制器负责让视图和模型同步。这一共有两步:当 model 对象改变的时候,视图应该随之改变以反映模型的变化;当用户和控制器交互的时候,模型也应该做出相应的改变。

KVO 能帮助我们让视图和模型保持同步。控制器可以观察视图依赖的属性变化。

1.使用:

1.1.注册与解除注册

NSKeyValueObserverRegistration 的 category 方法将观察者对象与被观察者对象注册与解除 注册:

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath opt ions:(NSKeyValueObservingOptions)options context:(void *)context;

- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

这两个方法的定义在 Foundation/NSKeyValueObserving.h 中

1.2.处理变更通知
观察者需要实现名为 NSKeyValueObserving 的 category 方法来处理收到的变更通知:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object chan
ge:(NSDictionary *)change context:(void *)context;

在这里,change 这个字典保存了变更信息,具体是哪些信息取决于注册时
的 NSKeyValueObservingOptions。

2 手动实现键值观察

  • 首先,需要手动实现属性的 setter 方法,并在设置操作的前后分别调用 willChangeValueForKey: 和 didChangeValueForKey 方法,这两个方法用于通知系统该
    key 的属性值即将和已经变更了;
  • 其次,要实现类方法 automaticallyNotifiesObserversForKey,并在其中设置对该 key 不自动
    发送通知(返回 NO 即可)。这里要注意,对其它非手动实现的 key,要转交给 super 来处理。
 - (void) setAge:(int)theAge
{
[self willChangeValueForKey:@"age"];
age = theAge;
[self didChangeValueForKey:@"age"];
} + (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key
{
if ([key isEqualToString:@"age"])
{
return NO;
}
return [super automaticallyNotifiesObserversForKey:key];
}

3键值观察依赖键

有时候一个属性的值依赖于另一对象中的一个或多个属性,如果这些属性中任一属性的值发生变更,被依

赖的属性值也应当为其变更进行标记。因此,object 引入了依赖键。

/*********************************************/

/******************待续*************************/

4.键值观察的实现

KVO 是通过 isa-swizzling 实现的。

当某个类的对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的 setter 方法。

派生类在被重写的 setter 方法实现真正的通知机制,就如前面手动实现键值观察那样。这么做是基于设置属性会调用 setter 方法,而通过重写就获得了 KVO 需要的通知机制

demo

1 Foo * anything = [[Foo alloc] init]; Foo * x = [[Foo alloc] init];
 2 Foo * y = [[Foo alloc] init]; 3 
Foo * xy = [[Foo alloc] init];

Foo * control = [[Foo alloc] init]; [x addObserver:anything forKeyPath:@"x" options: context:NULL];
[y addObserver:anything forKeyPath:@"y" options: context:NULL];
[xy addObserver:anything forKeyPath:@"x" options: context:NULL];
[xy addObserver:anything forKeyPath:@"y" options: context:NULL];

创建了四个对象,x 对象的 x 属性被观察,y 对象的 y 属性被观察,xy 对象的 x 和 y 属 性均被观察,参照对象 control 没有属性被观察。

结果

如果使用对象的 -class 方面输出类名始终为:Foo,这是因为新诞生的派生类 重写了 -class 方法声称它就是起初的基类,(将被观察对象的isa 指向这个派生类)

只有使用 runtime 函数 object_getClass 才能一睹芳容: NSKVONotifying_Foo。

x,y 以及 xy 三个被观察对象真正的类型都是 NSKVONotifying_Foo, 而且该类实现了:setY:, setX:, class, dealloc, _isKVOA 这些方法。其中 setX:, setY:, class 和

dealloc 前面已经讲到过,私有方法 _isKVOA 估计是用来标示该类是一个 KVO 机制声称的类。在这里 Objective C 做了一些优化,它对所有被观察对象只生成一个派生类,该派生类实现所有被观察对象的 setter 方法,这样就减少了派生类的数量,

OC之KVC,KVO的更多相关文章

  1. 阶段性总结⓵触摸事件&手势识别⓶Quartz2D绘图⓷CALayer图层⓸CAAnimation⓹UIDynamic UI动力学⓺KVC&KVO

    知识点复习   1. 触摸事件&手势识别   1> 4个触摸事件,针对视图的 2> 6个手势识别(除了用代码添加,也可以用Storyboard添加)   附加在某一个特定视图上的, ...

  2. IOS开发之KVC KVO KVB

    KVC(Key Value Coding) KVO(Key Value Observing) KVB(Key Value Binding) KVO是Cocoa的一个重要机制,他提供了观察某一属性变化的 ...

  3. KVC/KVO原理详解及编程指南

    一.简介 1.KVC简介 2.KVO简介 二.KVC相关技术 1.Key和Key Path 2.点语法和KVC 3.一对多关系(To-Many)中的集合访问器方法 4.键值验证(Key-Value V ...

  4. 【转】 KVC/KVO原理详解及编程指南

    原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 前言: 1.本文基本不讲KVC/KVO的用法,只结合网上的资料说说对这种技术的 ...

  5. kvc/kvo复习

    kvc/kvo复习 1 小问题 '[<XMGPerson 0x7fb8a8f30220> setValue:forUndefinedKey:]: this XMGPerson * pers ...

  6. 转:KVC/KVO原理详解及编程指南

      作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或 ...

  7. QF——OC中的KVC,KVO

    KVC: (Key Value Coding) 键值编码 所谓KVC,其实就是不通过set和get方法访问对象属性,而是通过属性名字符串动态的去读取属性.KVC其实也是OC反射机制的一种运用. 之所以 ...

  8. 设计模式之观察者模式(关于OC中的KVO\KVC\NSNotification)

    学习了这么久的设计模式方面的知识,最大的感触就是,设计模式不能脱离语言特性.近段时间所看的两本书籍,<大话设计模式>里面的代码是C#写的,有一些设计模式实现起来也是采用了C#的语言特性(C ...

  9. [转] iOS (OC) 中 KVC 与 KVO 理解

    转自: http://magicalboy.com/kvc_and_kvo/ KVC 与 KVO 是 Objective C 的关键概念,个人认为必须理解的东西,下面是实例讲解. Key-Value ...

随机推荐

  1. 敏捷开发(十)- Scrum每日例会

    本文主要是为了检测你对SCRUM 评估会议的了解和使用程度, 通过本文你可以检测一下     1.你们的SCRUM 没人例会的过程和步骤    2.SCRUM 每日例会的输出结果一.会议目的      ...

  2. CodeForces 706D Vasiliy's Multiset

    字典树. 比较经典的题目了.把每一个数字都插入到字典树中,询问的时候如果$x$的第$i$位是$p$,那么尝试着在字典树上往$pXOR1$的节点走下去,没有$pXOR1$节点的话再走$p$的.删除操作的 ...

  3. C# 语言规范_版本5.0 (第8章 语句)

    1. 语句 C# 提供各种语句.使用过 C 和 C++ 编程的开发人员熟悉其中大多数语句. statement: labeled-statement declaration-statement emb ...

  4. ArcGIS 10.5 named user介绍

    1           Named user概述 1.1    Named user简介 Named user是ArcGIS产品自10.3版本正式推出的一种以用户为中心的授权机制,也称"授权 ...

  5. 为什么重写equals()必须重写hashCode()

    主要原因是因为hashCode是用对象的内部地址转换成一个整数的,而equals比较得是两个对象,或者是两个对象的内容 如果你重写了equals,而保留hashCode的实现不变,那么很可能两个对象明 ...

  6. JPA 系列教程21-JPA2.0-@MapKeyColumn

    @MapKeyColumn 用@JoinColumn注解和@MapKeyColumn处理一对多关系 ddl语句 CREATE TABLE `t_employee` ( `id` bigint(20) ...

  7. CBC之php java兼容版本

    网上搜了N多代码,都是你抄我的,我抄你的,着实让人无语对苍天.经过多番资料的查找,php与java的cbc加密.解密结果终于一致了,代码如下: Java加密解密类: package main; imp ...

  8. mpich2 下运行时出现“由于目标计算机积极拒绝,无法连接”的错误

    进行mpi并行编程时候,win8下使用mpich2时候,安装目录下找到wmpiexec.exe程序打开,填入编写好的.exe程序地址并制定执行的任务数目的想要运行时候,出现错误: unable to  ...

  9. BeanUtils属性

    1.copyproperties:拷贝方法      (1).当源对象(a)中存在一个java.sql.Date类型的属性并且值为null,目标对象(b)中也存在这个同名同类型的属性.把a对象属性值c ...

  10. 2016年团体程序设计天梯赛-决赛 L2-3. 互评成绩(25)

    学生互评作业的简单规则是这样定的:每个人的作业会被k个同学评审,得到k个成绩.系统需要去掉一个最高分和一个最低分,将剩下的分数取平均,就得到这个学生的最后成绩.本题就要求你编写这个互评系统的算分模块. ...