【IOS 开发学习总结-OC-14】★★★objective-c面向对象之——KVO(键值监听)
来源:互联网 发布:淘宝卖的100多充气娃娃 编辑:程序博客网 时间:2024/06/06 18:53
KVO:键值监听,全称 keyValueObserving,是观察者模式的一种。NSKeyValueObserving协议为 KVO提供支持。NSObject 遵守了该协议,因此NSObject的子类(所有 oc 类都是NSObject的子类)都可以使用该协议中的方法。
监听器的一些常用方法
下面是关于监听器的一些常用方法:
KVO的运行机制
KVO的运行机制:
上面这个图不是很直观。我又找了一个形象点的图:
KVO 编程的步骤
KVO 编程的步骤:
1. 为被监听对象(通常是数据模型组件)注册监听器。
2. 重写监听器的 observeValueForKeyPath:ofObject:change:context:
方法。
3. 移除监听器。
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
程序示例
程序示例(这里用一个简单的类来模拟视图组件):
FKItem.h
#import <Foundation/Foundation.h>@interface FKItem : NSObject// 使用@property定义两个属性@property(nonatomic , copy) NSString* name;@property(nonatomic , assign) int price;@end
FKItem.m
#import "FKItem.h"@implementation FKItem@synthesize name;@synthesize price;- (void)setNilValueForKey: (id)key{ // 如果尝试将key为price的属性设为nil if([key isEqualToString:@"price"]) { // 将该price设置为0 price = 0; } else { // 回调父类的setNilValueForKey,执行默认行为 [super setNilValueForKey: key]; }}@end
FKItemView.h
#import <Foundation/Foundation.h>#import "FKItem.h"@interface FKItemView : NSObject// 使用@property定义两个属性@property(nonatomic , weak) FKItem* item;- (void) showItemInfo;@end
FKItemView.m
#import "FKItemView.h"@implementation FKItemView@synthesize item = _item;- (void) showItemInfo{ NSLog(@"item物品名为%@,物品价格为:%d" , self.item.name , self.item.price);}// 自定义setItem:方法- (void) setItem:(FKItem*) item{ self->_item = item; // 为item添加监听器,监听item的name属性的改变 [self.item addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil]; // 为item添加监听器,监听item的price属性的改变 [self.item addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew context:nil]; }// 重写该方法,当被监听的数据模型发生改变时,就会回调监听器的该方法- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ NSLog(@"--observeValueForKeyPath方法被调用--"); // 获取修改时所设置的数据 NSLog(@"被修改的keyPath为:%@", keyPath); NSLog(@"被修改的对象为:%@", object); NSLog(@"新被修改的属性值为:%@", [change objectForKey:@"new"]); NSLog(@"被修改的上下文为:%@", context);}- (void) dealloc{ // 删除监听器 [self.item removeObserver:self forKeyPath:@"name"]; [self.item removeObserver:self forKeyPath:@"price"]; }@end
FKItemViewTest.m
#import "FKItemView.h"int main(int argc , char * argv[]){ @autoreleasepool{ // 创建FKItem对象 FKItem* item = [[FKItem alloc] init]; // 设置item的属性 item.name = @"疯狂iOS讲义"; item.price = 109; // 创建FKItemView对象 FKItemView* itemView = [[FKItemView alloc] init]; // 将itemView的item属性设为item。 itemView.item = item; [itemView showItemInfo]; // 再次更给item对象的属性,将会激发监听器的方法 item.name = @"疯狂XML讲义"; item.price = 69; }}
编译,运行后的结果:
2015-09-24 09:39:33.418 923[5168:238493] item物品名为疯狂iOS讲义,物品价格为:1092015-09-24 09:39:33.421 923[5168:238493] --observeValueForKeyPath方法被调用--2015-09-24 09:39:33.422 923[5168:238493] 被修改的keyPath为:name2015-09-24 09:39:33.422 923[5168:238493] 被修改的对象为:<FKItem: 0x79712850>2015-09-24 09:39:33.423 923[5168:238493] 新被修改的属性值为:疯狂XML讲义2015-09-24 09:39:33.423 923[5168:238493] 被修改的上下文为:(null)2015-09-24 09:39:33.423 923[5168:238493] --observeValueForKeyPath方法被调用--2015-09-24 09:39:33.424 923[5168:238493] 被修改的keyPath为:price2015-09-24 09:39:33.424 923[5168:238493] 被修改的对象为:<FKItem: 0x79712850>2015-09-24 09:39:33.424 923[5168:238493] 新被修改的属性值为:692015-09-24 09:39:33.425 923[5168:238493] 被修改的上下文为:(null)
- 【IOS 开发学习总结-OC-14】★★★objective-c面向对象之——KVO(键值监听)
- 【IOS 开发学习总结-OC-13】★★objective-c面向对象之——KVC(键值编码)
- 【IOS 开发学习总结-OC-17】★★objective-c面向对象之——多态
- 【IOS 开发学习总结-OC-9】★ objective-c面向对象之——方法
- 【IOS 开发学习总结-OC-8.1】★★ objective-c面向对象之——类和对象(上)
- 【IOS 开发学习总结-OC-8.2】★★ objective-c面向对象之——类和对象(下)
- 【IOS 开发学习总结-OC-16】★★objective-c面向对象之——类的继承
- 【IOS 开发学习总结-OC-19】★★objective-c面向对象之——类别与扩展
- 【IOS 开发学习总结-OC-11】★objective-c面向对象之——封装和访问控制符
- 【IOS 开发学习总结-OC-12】★objective-c面向对象之——合成存取方法与点语法
- 【IOS 开发学习总结-OC-20】★★★objective-c面向对象——协议(protocol)
- 【IOS 开发学习总结-OC-21】★★★objective-c面向对象——委托/代理(delegate)
- 【IOS 开发学习总结-OC-18】★★objective-c面向对象之——OC的包装类与对象处理
- 【IOS 开发学习总结-OC-15】objective-c面向对象之——对象初始化
- 【IOS 开发学习总结-OC-10】★ objective-c面向对象之——成员变量,模拟类变量,单例模式
- 【IOS 开发学习总结-OC-27】★★objective-c之foundation 框架——对象复制
- 【IOS 开发学习总结-OC-29】★★objective-c之foundation 框架——(集合类)数组
- 【IOS 开发学习总结-OC-29】★★objective-c之foundation 框架——(集合类)数组
- UltraEdit中粘贴问题
- 桥接表
- ioctl 变成了 unlocked_ioctl
- gnome桌面的美化
- 黑马程序员——Java概述
- 【IOS 开发学习总结-OC-14】★★★objective-c面向对象之——KVO(键值监听)
- Cocos2dx的C++和Java的互相调用(EasyNDK)
- NDK c 文件引用c++ 函数
- SpringMVC中使用Interceptor拦截器
- test
- 测试要点1.0
- 常用的IOS动画效果
- 线性表之顺序表
- 并发下常见的加锁及锁的PHP具体实现