键值观察之KVO——即观察者模式的应用
2015-09-20 23:43
274 查看
KVO的基本概念
1、基本概念:
Key Value Observing ,直译为:基于键值的观察者。它提供一种机制,当指定的对象的属性被修改后,则对象就会接收到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。(常用于监听进度条的值)
与NSNotification不同,键-值 观察中并没有所谓的中心对象来为观察者提供变化通知。取而代之的,当有变化时,通知被直接发送至处于观察状态的对象。NSObject提供这种基础的 键-值 观察实现方法。
我们可以观察任意对象属性,包括简单属性,一对一或一对多关系。对多关系的观察者将会被被告知发生变化的类型-也就是任意发生变化的对象。
键-值 观察为所有对象提供自动观察兼容性。我们可以通过禁用自动观察通知并实现手动通知来筛选通知。
2、代理与观察者的区别就是:代理是一对一,观察者是一对多的。
就是说一个对象的代理只能是一个,就好比一次只能给一个人打电话一样,而观察者就好比是广播,所有人都会受到通知。代理只能实现一对一是无法实现一对多的。
新建工程:
创建一个孩子类:
编辑Child.h如下:
编辑Nurse.h如下:
在main.m中编辑如下:
运行结果如下:
1、基本概念:
Key Value Observing ,直译为:基于键值的观察者。它提供一种机制,当指定的对象的属性被修改后,则对象就会接收到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。(常用于监听进度条的值)
与NSNotification不同,键-值 观察中并没有所谓的中心对象来为观察者提供变化通知。取而代之的,当有变化时,通知被直接发送至处于观察状态的对象。NSObject提供这种基础的 键-值 观察实现方法。
我们可以观察任意对象属性,包括简单属性,一对一或一对多关系。对多关系的观察者将会被被告知发生变化的类型-也就是任意发生变化的对象。
键-值 观察为所有对象提供自动观察兼容性。我们可以通过禁用自动观察通知并实现手动通知来筛选通知。
2、代理与观察者的区别就是:代理是一对一,观察者是一对多的。
就是说一个对象的代理只能是一个,就好比一次只能给一个人打电话一样,而观察者就好比是广播,所有人都会受到通知。代理只能实现一对一是无法实现一对多的。
新建工程:
创建一个孩子类:
编辑Child.h如下:
// // Child.h // KVOTest // // Created by yanlu guo on 13-7-28. // Copyright (c) 2013年 河北科技大学. All rights reserved. // #import <Foundation/Foundation.h> @interface Child : NSObject { NSInteger happyVal; } @property(nonatomic,assign) NSInteger happyVal; @end编辑Child.m如下:
// // Child.m // KVOTest // // Created by yanlu guo on 13-7-28. // Copyright (c) 2013年 河北科技大学. All rights reserved. // #import "Child.h" @implementation Child @synthesize happyVal; // 可以发现孩子类中并没有护士的对象 但是护士仍然受到了通知 // 并不只是护士 ,而是所有的类的中都可以为孩子添加一个观察者 -(id)init{ if(self = [super init]){ self.happyVal = 100; [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES]; } return self; } -(void) timerAction:(NSTimer *) timer{ self.happyVal--; // 注意:使用点语法即 调用set方法才能触发监听操作 } @end新建护士类 当孩子快乐值减到一定程度时 观察者就会通知护士执行照顾孩子的操作
编辑Nurse.h如下:
// // Nurse.h // KVOTest // // Created by yanlu guo on 13-7-28. // Copyright (c) 2013年 河北科技大学. All rights reserved. // #import <Foundation/Foundation.h> #import "Child.h" @interface Nurse : NSObject { Child * child; } @property(nonatomic,retain) Child * child; -(id) initWithChild:(Child *) _child; @end编辑Nurse.m如下:
// // Nurse.m // KVOTest // // Created by yanlu guo on 13-7-28. // Copyright (c) 2013年 河北科技大学. All rights reserved. // #import "Nurse.h" @implementation Nurse @synthesize child; -(id) initWithChild:(Child *) _child{ if(self = [super init]){ child = [_child retain]; // 使用KVO 为child添加一个观察者 用于监听happyVal是否被修改了 // 把新旧值都传过来 self表示在当前类中执行监听方法 // | 表示把新的值和旧的值(即监听的happyVal的新值和旧值都传过来) [child addObserver:self forKeyPath:@"happyVal" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:@"xxx"]; } return self; } -(void) dealloc{ [child removeObserver:self forKeyPath:@"happyVal"]; [child release]; [super dealloc]; } // 一旦监听的happyVal的值被修改就会触发下面的方法 // 以下方法是NSObject的方法 触发监听后执行 与前面的 addObserver方法是配套使用的 -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ NSNumber *happyValue = [change objectForKey:@"new"]; NSInteger value = happyValue.integerValue; NSLog(@"快乐值是:%0.1f %%",value/100.0* 100); if (value< 80) { // 如果小孩的欢乐值小于80 就会哭 [self play]; // 观察者就会通知保姆照顾小孩 [child setHappyVal:100]; // 孩子的欢乐值又重新变为100 } } -(void)play { NSLog(@"陪小孩玩"); } @end
在main.m中编辑如下:
// // main.m // KVOTest // // Created by yanlu guo on 13-7-28. // Copyright (c) 2013年 河北科技大学. All rights reserved. // #import <Foundation/Foundation.h> #import "Child.h" #import "Nurse.h" int main (int argc, const char * argv[]) { @autoreleasepool { Child * child = [[Child alloc] init]; [[Nurse alloc] initWithChild:child]; [[NSRunLoop currentRunLoop] run]; } return 0; }
运行结果如下:
相关文章推荐
- Servlet请求
- 从关系型数据库到非关系型数据库
- Caused by: org.hibernate.InvalidMappingException: Unable to read XML
- Android Studio常用插件
- IOS UIBezierPath使用方法详解
- servlet配置笔记
- 【Python】 Missing parentheses in call to 'print'
- Fibonacci数列求和
- python字符串基础
- NSURLProtocol的使用
- OCP-V13-710
- js处理数组问题,以及数组转化问题
- MVC 过滤器
- 剑指offer | 最小的K个数
- 人生与股市一起起伏,反而看淡了名利
- 3、数值数据类型及表示-2(符号常量的应用)
- 杭电OJ异或题
- DNS篇二(BIND运用)
- Android学习博(序)
- Lucas定理