我们知道在WPF、Silverlight中都有一种双向绑定机制,如果数据模型修改了之后会立即反映到UI视图上,类似的还有如今比较流行的基于MVVM设计模式的前端框架,例如Knockout.js。其实在ObjC中原生就支持这种机制,它叫做Key Value Observing(简称KVO)。KVO其实是一种观察者模式,利用它可以很容易实现视图组件和数据模型的分离,当数据模型的属性值改变之后作为监听器的视图组件就会被激发,激发时就会回调监听器自身。在ObjC中要实现KVO则必须实现NSKeyValueObServing协议,不过幸运的是NSObject已经实现了该协议,因此几乎所有的ObjC对象都可以使用KVO。

在ObjC中使用KVO操作常用的方法如下:

  • 注册指定Key路径的监听器: addObserver: forKeyPath: options:  context:
  • 删除指定Key路径的监听器: removeObserver: forKeyPathremoveObserver: forKeyPath: context:
  • 回调监听: observeValueForKeyPath: ofObject: change: context:

如何使用KVO呢?

首先,你要为你想观察的对象添加一个观察者代码如下:

[object addObserver: observer forKeyPath: @"frame" options: 0 context: nil];

调用方法是:

object : 被观察对象

observer: 观察对象

forKeyPath里面带上property的name,如UIView的frame、center等等

options: 有4个值,分别是:

NSKeyValueObservingOptionNew 把更改之后的值提供给处理方法

NSKeyValueObservingOptionOld 把更改之前的值提供给处理方法

NSKeyValueObservingOptionInitial 把初始化的值提供给处理方法,一旦注册,立马就会调用一次。通常它会带有新值,而不会带有旧值。

NSKeyValueObservingOptionPrior 分2次调用。在值改变之前和值改变之后。

注:例子里的0就代表不带任何参数进去

context: 可以带入一些参数,任何类型都可以,强制转就可以。

接下来观察到值的变化后该应该调用相关的方法来处理,这个方法是:

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

其中:

keyPath: 对应forKeyPath

  object:  被观察的对象

  change:  对应options里的NSKeyValueObservingOptionNew、NSKeyValueObservingOptionOld等

  context: 对应context

示例代码

头文件

 #import <Foundation/Foundation.h>

 @interface Student : NSObject
@property (nonatomic)NSString *name; @property (nonatomic)NSString *courseName; @property (nonatomic)double age; - (void)changeCourseName:(NSString *)newCourseName;
@end

实现文件

 #import "Student.h"

 @implementation Student

 - (id)init
{
if(self = [super init])
{ [self addObserver:self
forKeyPath:@"courseName"
options:NSKeyValueObservingOptionNew
|NSKeyValueObservingOptionOld
context:nil];
[self addObserver:self
forKeyPath:@"age"
options:NSKeyValueObservingOptionNew
|NSKeyValueObservingOptionOld
context:nil];
}
return self;
} - (void)changeCourseName:(NSString *)newCourseName{ _courseName = newCourseName; }
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if([keyPath isEqualToString:@"courseName"])
{
NSLog(@"课程发生了改变");
NSLog(@"新课程是:%@ 老课程是:%@",[change objectForKey:@"new"],[change objectForKey:@"old"]); }
else if([keyPath isEqualToString:@"age"])
{
NSLog(@"年龄发生了改变");
NSLog(@"新年龄是:%@ 老年龄是:%@",[change objectForKey:@"new"],[change objectForKey:@"old"]);
}
}
#pragma mark 重写销毁方法
-(void)dealloc//注意一定要移除监听
{
//[super dealloc];//注意启用了ARC,此处不需要调用
[self removeObserver:self forKeyPath:@"courseName"];
[self removeObserver:self forKeyPath:@"age"]; }
@end

调用函数

#import <Foundation/Foundation.h>
#import "Student.h"
#import "pageView.h" int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *student = [[Student alloc] init];
student.courseName = @"math";
student.age = ;
student.courseName = @"ddd";
student.age = ; }
return ;
}

输出结果

2015-07-10 14:59:13.074 TestKVO[1649:1396305] 课程发生了改变

2015-07-10 14:59:13.076 TestKVO[1649:1396305] 新课程是:math  老课程是:<null>

2015-07-10 14:59:13.076 TestKVO[1649:1396305] 年龄发生了改变

2015-07-10 14:59:13.076 TestKVO[1649:1396305] 新年龄是:10  老年龄是:0

2015-07-10 14:59:13.076 TestKVO[1649:1396305] 课程发生了改变

2015-07-10 14:59:13.076 TestKVO[1649:1396305] 新课程是:ddd  老课程是:math

2015-07-10 14:59:13.077 TestKVO[1649:1396305] 年龄发生了改变

2015-07-10 14:59:13.077 TestKVO[1649:1396305] 新年龄是:15  老年龄是:10

 

OC——关于KVO的更多相关文章

  1. 【Objective-C】OC中KVO的基本概念和使用方法

    基本概念: 键值观察是一种使用获取其他对象的特定属性变化的通知机制. 控制器层的绑定技术就是严重依赖键值观察获得模型层和控制器层的变化通知的. 对于不依赖控制器层类的应用程序,键值观察提供了一种简化的 ...

  2. iOS - KVO 键值观察

    1.KVO KVO 是 Key-Value Observing 的简写,是键值观察的意思,属于 runtime 方法.Key Value Observing 顾名思义就是一种 observer 模式用 ...

  3. OC学习篇之---通知(NSNotificationCenter)

    在前一篇文章中我们介绍了OC中很常用的两个技术:KVC和KVO: http://blog.csdn.net/jiangwei0910410003/article/details/41912937,今天 ...

  4. OC中另外的一个常用技术:通知(Notification)

    OC中另外的一个常用技术:通知(Nofitication)其实这里的通知和之前说到的KVO功能很想,也是用于监听操作的,但是和KVO不同的是,KVO只用来监听属性值的变化,这个发送监听的操作是系统控制 ...

  5. iOS之NSNotificationCenter通知中心使用事项

    其实这里的通知和之前说到的KVO功能很想,也是用于监听操作的,但是和KVO不同的是,KVO只用来监听属性值的变化,这个发送监听的操作是系统控制的,我们控制不了,我们只能控制监听操作,类似于Androi ...

  6. OC 观察者模式(通知中心,KVO)

    OC 观察者模式(通知中心,KVO) 什么是观察者模式??? A对B的变化感兴趣,就注册为B的观察者,当B发生变化时通知A,告知B发生了变化.这就是观察者模式. 观察者模式定义了一种一对多的依赖关系, ...

  7. QF——OC中的KVC,KVO

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

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

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

  9. OC学习篇之---KVC和KVO操作

    前一篇文章我们介绍了OC中最常用的文件操作:http://blog.csdn.net/jiangwei0910410003/article/details/41875015,那么今天来看一下OC中的一 ...

随机推荐

  1. Oracle异常汇总

    持续更新中,可参见https://hnuhell.gitbooks.io/oracle_errmg/content/或https://hnuhell.github.io/Oracle_ERRMG/上的 ...

  2. 第二章 [分布式CMS]

    结构系统:定义的后台 资源云:存在静态资源文件 文档云:文章内容 工具服务:模板.,公共类 Web服务:处理一下数据交互 为什么要做分布式了? 说实话,我也不太清楚,网上说在性能方面比较好,我的理解是 ...

  3. 用openssl库RSA加密解密

    #include <stdio.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include < ...

  4. Varnsih调用多台后端主机

    author:JevonWei 版权声明:原创作品 Varnsih调用多个后端主机 环境 Varnish 192.168.198.139 图片服务端 192.168.198.120 程序服务端 192 ...

  5. 后端路由项目由 gulp 改为 webpack 的踩坑实录

    前言 公司有个后端路由的项目是用 gulp 作为前端自动化构建工具,最近学习了一下 webpack,深感其强大,一狠心将其改成了 webpack 构建,以下是踩坑实录. gulp 先来说说原来的架构. ...

  6. ios 初体验<UIButton 控件>

    1.创建UIButton 跟其他方式不同,不是直接alloc,init 创建 用工厂化方式创建 UIButton *sureBtn = [UIButton buttonWithType:UIButto ...

  7. 移动端rem使用

    let $html=document.documentElement,windowW = window.innerWidth,ratio = windowW / 750if (windowW > ...

  8. 第1阶段——uboot分析之查找命令run_command函数和命令定义过程(6)

    本节主要学习,run_command函数命令查找过程,命令生成过程 1.run_command函数命令查找过程分析:在u-boot界面中(main_loop();位于u-boot-1.1.6/comm ...

  9. Rational Rose2013安装及破解教程

    1.下载地址:http://pan.baidu.com/s/1mhKGfHY 2.安装:解压缩文件"[Rational.Rose.Enterprise.Edition.2003].Softw ...

  10. ★电车难题的n个坑爹变种

    哲学家都不会做的电车难题变异 此题会答清华北大 "电车难题(Trolley Problem)"是伦理学领域最为知名的思想实验之一,其内容大致是: 一个疯子把五个无辜的人绑在电车轨道 ...