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. <hdu - 1863> 畅通工程 并查集和最小生成树问题

    本题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1863  Problem Description: 省政府“畅通工程”的目标是使全省任何两个村庄间都可以 ...

  2. Android中设定EditText的输入长度

    方法一:可以在layout xml中加上属性android:maxLength 比如: <EditText         android:id="@+id/editTextShow& ...

  3. Java模拟post-get提交

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ...

  4. hdu1029

    #include<iostream>#include<string.h>using namespace std;int main(){ int n,i; int t; int ...

  5. USACO 3.2 Contact

    ContactIOI'98 The cows have developed a new interest in scanning the universe outside their farm wit ...

  6. NASPhoto Station不只是储存的强大照片管理功能

    减少漫长的讨论时间,进而让你的艺术作品更符合客户需求.Photo Station 让你集中存储照片.随处分享及存取相簿并轻松收集朋友和客户反馈. 串流照片到大屏幕电视 DS photo 支援 Appl ...

  7. QLibraryInfo

        读取 qt.conf 文件, 获取 Qt Library 的信息.     通常会在以下三个路径查找conf文件:         :/qt/etc/qt.conf(使用资源系统时)      ...

  8. Angular React 和 Vue的比较

    Angular(1&2),React,Vue对比 一 数据流 数据绑定 Angular 使用双向绑定即:界面的操作能实时反映到数据,数据的变更能实时展现到界面. 实现原理: $scope变量中 ...

  9. 浙大 pat 1003 题解

    1003. Emergency (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue As an emerg ...

  10. centos7 安装openvswitch

    安装 1.安装依赖包:yum -y install openssl-devel wget kernel-devel 2.安装开发工具:yum groupinstall "Developmen ...