KVO(键值监听)详解
来源:互联网 发布:局域网演示软件 编辑:程序博客网 时间:2024/06/05 21:07
iOS通常会把应用程序组件分开成数据模型组件和视图组件,其中数据模型负责维护应用程序的状态数据,而视图组件负责显示数据模型组件内部的状态数据。对于上面的设计模式,如果程序存在的需求是:在数据模型组件的状态数据发生改变时,试图组件能动态的更新自己,及时显示数据模型组件更新后的数据。为了解决上面的需求,及时显示数据模型组件更新后的数据:
1、我们可以用通知中心,但是对于数据模型组件和视图模型组件之间都需要与iOS的消息中心耦合,而且每当数据模型组件的内部状态发生改变时,都需要向iOS的消息中心发送消息,这也是非常令人悲哀的事情。
2、那么如果我们用KVO那么就是很好的解决方案了,(键值监听机制)
下方方法:
addObserver: forKeyPath: options: context: 注册一个监听器用于监听指定的key路径
removeObserver: forKeyPath: 为key路径删除指定的监听器
removeObserver: forKeyPath: context:为key路径删除指定的监听器.只是多了一个context参数
当数据模型组件的key路径对应属性值发生改变时,作为监听器的视图组件将会被激发,假发是就会回调监听器自身的监听方法,该监听方法如下:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
}
由此可见,作为监听器的试图组件需要重写上方这个方法,重写该方法是就可以得到最新修改的数据,从而使用最新的数据来更新视图组件的显示。
从上面介绍不难看出,KVO编程的步骤如下:
1、为被监听对象(通常是数据模型组件)注册监听器
2、重写监听器的-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context方法。
下方用一个简单地类模拟视图组件,下方代码仔细看即可:
程序代码:LYXItem.h
#import <Foundation/Foundation.h>@interface LYXItem : NSObject@property(nonatomic,copy) NSString *name;@property(nonatomic,copy) NSString *price;@end
程序代码:LYXItemView.h
// Created by lyx on 16/2/11.// Copyright (c) 2016年 李云祥. All rights reserved.//#import <Foundation/Foundation.h>#import "LYXItem.h"@interface LYXItemView : NSObject//使用@property定义两个属性@property(nonatomic,weak) LYXItem * item;-(void)showItemInfo;@end
程序代码:LYXItemView.m
#import "LYXItemView.h"@implementation LYXItemView@synthesize item = _item;-(void)showItemInfo{ NSLog(@"item名为:%@,价格为%@",self.item.name,self.item.price);}//自定义setItem方法-(void)setItem:(LYXItem *)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
程序代码:main.m
#import <Foundation/Foundation.h>#import "LYXItemView.h"#import "LYXItem.h"int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... //创建item对象 LYXItem *item = [[LYXItem alloc]init]; item.name = @"IOS"; item.price = @"10"; LYXItemView *itemView = [[LYXItemView alloc]init]; //将itemView的item属性设为item itemView.item = item; [itemView showItemInfo]; //再次更改item的属性,将会激发监听器的方法 item.name = @"安卓"; item.price = @"100"; } return 0;}
输出下方代码:
2016-02-11 22:51:49.767 KVO操练[502:17531] item名为:IOS,价格为102016-02-11 22:51:49.768 KVO操练[502:17531] -------observeValueForKeyPath-----方法被调用2016-02-11 22:51:49.768 KVO操练[502:17531] 被修改的keyPath为:name2016-02-11 22:51:49.769 KVO操练[502:17531] 被修改的对象为:<LYXItem: 0x100304830>2016-02-11 22:51:49.769 KVO操练[502:17531] 新被修改的属性值是:安卓2016-02-11 22:51:49.769 KVO操练[502:17531] 被修改的上下文是:(null)2016-02-11 22:51:49.769 KVO操练[502:17531] -------observeValueForKeyPath-----方法被调用2016-02-11 22:51:49.769 KVO操练[502:17531] 被修改的keyPath为:price2016-02-11 22:51:49.769 KVO操练[502:17531] 被修改的对象为:<LYXItem: 0x100304830>2016-02-11 22:51:49.770 KVO操练[502:17531] 新被修改的属性值是:1002016-02-11 22:51:49.770 KVO操练[502:17531] 被修改的上下文是:(null)Program ended with exit code: 0
可以看出,当使用KVO后,此时的程序当被监听的数据模型组件LYXItem的属性发生改变,监听器的监听方法就会被激发。要是在视图控制器上,那么这里的UI就会进行改变。
- KVO(键值监听)详解
- 详解键值观察(KVO)
- Objective-C 【KVO(键值监听)】
- KVO(键值监听模式)
- OC键值监听(KVO)
- 键值监听KVO机制
- 024.KVO 键值监听
- 键值监听KVO
- 024.KVO 键值监听
- KVO 键值监听者
- KVO键值监听
- 键值监听KVO
- 键值监听---KVO
- KVO键值监听
- KVO -- 键值监听
- iOS键值编码(KVC)与键值监听(KVO)
- 键值编码(KVC)、键值监听(KVO)
- KVO的使用(键值监听)
- 当点击按钮时,阻止软键盘关闭
- 119. Pascal's Triangle II LeetCode
- 面试笔试杂项积累-leetcode 216-220
- django signal and contenttypes初探,可用于好友最新动态,新鲜事,消息通知等
- Oracle第学习四天
- KVO(键值监听)详解
- 实现Socket服务端监听(模拟10086在线服务)
- java中的this
- bzoj1005: [HNOI2008]明明的烦恼
- Atitit.跨语言反射api 兼容性提升与增强 java c#。Net php js
- Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
- VS2015中cout、cin未声明的标识符错误的处理
- ytr920609ytr
- HDU 2126(01背包扩展,记录方案数)