KVO:key value observer 键值对的观察者
 
功能:给对象属性添加观察者,用来时时监测对象属性值的改变,一旦属性值发生了改变,观察者就做出相应的反应,提醒用户。在应用中,针对MVC模式,数据库中的数据模型发生变化时,引起视图界面的改变,此时使用KVO进行数据的监测是一个不错的机制。
 
 
步骤:
1.添加观察者
2.接收变动通知
3.删除观察者
 
详细介绍:
 
键值通知枚举

typedef NS_OPTIONS(NSUInteger, NSKeyValueObservingOptions) {

NSKeyValueObservingOptionNew = 0x01,

NSKeyValueObservingOptionOld = 0x02,

NSKeyValueObservingOptionInitial = 0x04,

NSKeyValueObservingOptionPrior= 0x08

};

内置的通知键

FOUNDATION_EXPORT NSString *const NSKeyValueChangeKindKey;

FOUNDATION_EXPORT NSString *const NSKeyValueChangeNewKey;

FOUNDATION_EXPORT NSString *const NSKeyValueChangeOldKey;

FOUNDATION_EXPORT NSString *const NSKeyValueChangeIndexesKey;

FOUNDATION_EXPORT NSString *const NSKeyValueChangeNotificationIsPriorKey ;

@interface NSObject(NSKeyValueObserving)

//接受被观察者发出变动后的通知

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

@end

@interface NSObject(NSKeyValueObserverRegistration)

//通过键给对应的属性添加观察者

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

//删除观察者

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

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

@end

@interface NSArray(NSKeyValueObserverRegistration)————— 数组的KVO机制

NSIndexSet 是个无符号整数集合。集合中的元素不可变的、不可重复。常被用来当作索引使用

//通过键给对应的数组中指定索引的属性添加观察者

- (void)addObserver:(NSObject *)observer toObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

//删除观察者

- (void)removeObserver:(NSObject *)observer fromObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath context:(void *)context;

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

//通过键给对应的数组添加观察者

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

//删除观察者

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

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

@end

@interface NSSet(NSKeyValueObserverRegistration)—————集合的KVO机制

//通过键给对应的set集合添加观察者

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

//删除观察者

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

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

@end

@interface NSObject(NSKeyValueObserverNotification)————观察者通知

//对于单个对象

- (void)willChangeValueForKey:(NSString *)key;

- (void)didChangeValueForKey:(NSString *)key;

//对于array数组

- (void)willChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key;

- (void)didChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key;

//对于set集合

- (void)willChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects;

- (void)didChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects;

@end

具体演示实例如下:

要求:将人设置为股票的观察者,一旦股票价格发生改变,就立刻发送即时信息。

准备工作:

在控制器视图中添加一个按钮控件并关联事件IBAction,用来点击时改变股票的价格,需要的文件相关截图为:

   

以下就是代码的实现了:

Person人类:

Person.h

//声明属性

#import <Foundation/Foundation.h>

@interface Person : NSObject
{
NSString *_name;
}
@end

Perosn.m

//接受观察者发来的即时信息

#import "Person.h"

@implementation Person

//接收被观察者发生变动后的通知
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"keyPath:%@,object:%@,change:%@",keyPath,object,change);
}
@end

Stock股票类:

Stock.h

//声明属性

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> @interface Stock : NSObject
{
NSString *_name;
CGFloat _price;
}
@end

ViewController控制器类

//声明属性

#import "ViewController.h"
#import "Person.h"
#import "Stock.h" @interface ViewController ()
@property (strong,nonatomic)Person *person;
@property (strong,nonatomic)Stock *stock;
@end @implementation ViewController

//按钮事件,点击时改变股票的价格

//按钮事件,改变股票价格
- (IBAction)buttonClicked:(UIButton *)sender
{
CGFloat price = [[self.stock valueForKey:@"_price"] floatValue]; [self.stock setValue:@(price+0.1) forKey:@"_price"];
}

//创建对象并添加观察者

- (void)viewDidLoad {
[super viewDidLoad];
//创建人和股票对象
self.person = [[Person alloc]init];
[self.person setValue:@"Tom" forKey:@"_name"]; self.stock = [[Stock alloc]init];
[self.stock setValue:@"sh0001" forKey:@"_name"];
[self.stock setValue:@12.5 forKey:@"_price"]; //添加观察者(观察股票的变动)
[self.stock addObserver:self.person forKeyPath:@"_price" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

//程序结束,删除观察者

-(void)dealloc
{
//删除观察者
[self.stock removeObserver:self.person forKeyPath:@"_price"];
}

演示结果如下:

点击第一次,输出股票价格更新即时信息

-- ::56.298 -KVO[:] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
kind = ;
new = "12.6";
old = "12.5";
}

点击第二次,输出股票价格更新即时信息

-- ::56.298 -KVO[:] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
kind = ;
new = "12.6";
old = "12.5";
}
-- ::44.913 -KVO[:] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
kind = ;
new = "12.70000038146973";
old = "12.6";
}

点击第三次,输出股票价格更新即时信息

-- ::56.298 -KVO[:] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
kind = ;
new = "12.6";
old = "12.5";
}
-- ::44.913 -KVO[:] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
kind = ;
new = "12.70000038146973";
old = "12.6";
}
-- ::09.448 -KVO[:] keyPath:_price,object:<Stock: 0x7f9679482c40>,change:{
kind = ;
new = "12.80000076293945";
old = "12.70000038146973";
}

Objective-C:KVO机制的更多相关文章

  1. KVO机制浅析和实例演示

    什么是KVO? KVO是Key-Value-Observing的缩写,通过KVO这种机制对象可以通过它得到其他对象的某个属性的变更通知.这种机制在MVC模式下显得更为重要,KVO可以让视图对象经过控制 ...

  2. 转:KVC与KVO机制

    由于Objective-C是基于Smalltalk进行设计的,所以它具有动态加载.动态绑定等特性.Key-value coding (KVC) 和 key-value observing (KVO) ...

  3. KVO机制

    KVO,全称为Key-Value Observing,是iOS中的一种设计模式,用来监测对象的某些属性的实时变化情况并作出响应 首先,假设我们的目标是在一个UITableViewController内 ...

  4. iOS 常用设计模式和机制之KVO

    KVO http://blog.kyleduo.com/2014/10/20/ios_learning-kvo/ 定义: KVO:Key-Value Observing,是Foundation框架提供 ...

  5. 谈KVC、KVO(重点观察者模式)机制编程

    一不小心,小明在<跟着贝尔去冒险>这个真人秀节目中看到了“一日警察,一世警察”的Laughing哥,整个节目除了贝尔吃牛睾丸都不用刀叉的不雅餐饮文化外,还是镜头少普通话跟小明一样烂的Lau ...

  6. [深入浅出Cocoa]详解键值观察(KVO)及其实现机理

    一,前言 Objective-C 中的键(key)-值(value)观察(KVO)并不是什么新鲜事物,它来源于设计模式中的观察者模式,其基本思想就是: 一个目标对象管理所有依赖于它的观察者对象,并在它 ...

  7. OC之KVC,KVO

    KVO简介 在 Cocoa 的模型-视图-控制器 (Model-view-controller)架构里,控制器负责让视图和模型同步.这一共有两步:当 model 对象改变的时候,视图应该随之改变以反映 ...

  8. iOS---观察者模式之--->KVO

    文章结构如下: Why? (为什么要用KVO) What? (KVO是什么) How? ( KVO怎么用) More (更多细节) 原理 自己实现KVO 在我的上一篇文章浅谈 iOS Notifica ...

  9. 11. KVC And KVO

    1. KVC And KVO  的认识 KVC/KVO是观察者模式的一种实现  KVC全称是Key-value coding,翻译成键值编码.顾名思义,在某种程度上跟map的关系匪浅.它提供了一种使用 ...

随机推荐

  1. python 基础 习题

    1.执行 Python 脚本的两种方式2.简述位.字节的关系 1Byte = 8bits 3.简述 ascii.unicode.utf-8.gbk 的关系 都是字符集,unicode兼容其他3种字符集 ...

  2. linux命令(43):cal命令

    cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历.“阳历”又名“太阳历”,系以地球绕行太阳一周为一年,为西方各国所通用,故又名“西历”. 1.命令格式: cal  ...

  3. POJ 2912 Rochambeau(种类并查集+枚举)

    题目链接:http://poj.org/problem?id=2912 题目大意:n个人玩,玩石头剪刀布游戏,其中1人是裁判,剩下的n-1个人分为3组, 他们商量好了,相同组的人每次都出相同的手势,不 ...

  4. HDU-5351

    MZL's Border Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  5. Linux安装mysql.8.0.12

    1. linux安装mysql8.0.12,亲测可用. 以下是安装过程中出现的问题: 1 [root@localtest1 file]# systemctl start mysqld 2 Job fo ...

  6. Git 分支 - 分支的新建

    https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA% ...

  7. hdu 2444(染色法判断二分图+最大匹配)

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  8. oracle 优化方案小记

    1. 目前状况 1.1 表空间未合理规划,导致所有的用户下的所有表都创建在默认的表空间下 oracle 使用过程中未针对特定数据表进行特定的表空间规划,导致目前实例中所有的数据库表都存储中默认的表空间 ...

  9. 洛谷P1120 小木棍 [搜索]

    题目传送门 题目描述乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍 ...

  10. HashMap 不能并发

    问题的症状 从前我们的Java代码因为一些原因使用了HashMap这个东西,但是当时的程序是单线程的,一切都没有问题.后来,我们的程序性能有问题,所以需要变成多线程的,于是,变成多线程后到了线上,发现 ...