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. 将递归函数非递归化的一般方法(cont)

    本文通过模拟汇编里的stack机制,构建一个自己的stack,然后将上一篇blog末尾的递归函数void bst_walk(bst_node_t *root)非递归化. o libstack.h #i ...

  2. 【 VS 插件开发 】二、了解Vs插件结构

    [ VS 插件开发 ]二.了解Vs插件结构

  3. 设计模式 -- 中介者设计模式 (Mediator Pattern)

    中介者模式的定义:将多对多关系分散为一对多的关系,将网状结构变成星状结构,降低复杂度,提高扩展性. 角色: Mediator :抽象中介者角色,以抽象类的方式实现,生命具体对象,以及抽象方法: Con ...

  4. 敏捷开发(五)- 框架SCRUM内容

    本文主要是为了检测你对SCRUM的了解和使用程度,通过本文你可以检测一下     1.你们的SCRUM项目中各个角色是否合格,    2.SCRUM上面需要的会议是否有遗留,会议过程是否正确    3 ...

  5. HTC与英特尔联手打造无线VR解决方案

    除了TPCAST无线附件组件之外,HTC早前还宣布了与英特尔合作研发WiGig无线VR解决方案,他们还愿意寻找更多的合作伙伴以带来进一步的解决方案. HTC希望确保其Vive头显可以实现无线升级,让用 ...

  6. document对象相关的几个常用的方法

    方法  描述 var newP=createElement("p"); 创建了一个p标签,p也可替换为div,span等 var oldTxt=createTextNode(&qu ...

  7. html-webpack-plugin

    插件地址:https://www.npmjs.com/package/html-webpack-plugin 这个插件用来简化创建服务于 webpack bundle 的 HTML 文件,尤其是对于在 ...

  8. Tomcat多域名的配置

    有时候我们有好几个项目需要发布在同一个tomcat服务器上,每个项目有不同的域名.这就需要在tomcat里配置多域名,添加多个虚拟主机. 主要在server.xml里面设置: 在<Engine& ...

  9. code style

    http://www.jianshu.com/p/0a984f999592# https://github.com/drakeet/LayoutFormatter https://github.com ...

  10. linux 通过pid寻找程序路径的最简单命令

    在linux实际操作命令中,查看pid的方式有很多种,通过pid找程序路径的方式也有好几个,但是可能大家都忽略的一个很简单也是很实用的命令:pwdx. 比如要查找某个java编写的程序运行情况可通过j ...