key-value observing (键值监测)

上传人:第*** 文档编号:31073488 上传时间:2018-02-04 格式:DOC 页数:16 大小:128.50KB
返回 下载 相关 举报
key-value observing (键值监测)_第1页
第1页 / 共16页
key-value observing (键值监测)_第2页
第2页 / 共16页
key-value observing (键值监测)_第3页
第3页 / 共16页
key-value observing (键值监测)_第4页
第4页 / 共16页
key-value observing (键值监测)_第5页
第5页 / 共16页
点击查看更多>>
资源描述

《key-value observing (键值监测)》由会员分享,可在线阅读,更多相关《key-value observing (键值监测)(16页珍藏版)》请在金锄头文库上搜索。

1、Key-Value Observing (键值监测)简介KVO 是一套当目标对象的属性值改变时观察者对象能够接受到通知的机制。必须先理解KVC 才能更好的理解 KVO,前者是后者的实现基础。 这样的通信机制在 MVC 设计模式很是常见实现过程简单来说分为 3 步: 1、添加观察这和监测对象 2、监测对象改变 3、收到值改变通知,处理后续逻辑 举个生活中的例子就是给银行卡开通短信通知的业务,总体也是分 3 步“ 1、去银行办理短信业务 2、账号财产变动 3、收到短信通知 KVO 是框架级别的服务,无需自己发送通知,使用方便,基本不需要添加额外代码即可使用。详情为了使用 KVO,必须满足以下 3

2、步1、目标对象的属性,必须支持 KVO2、注册观察者与被观察者 addObserver:forKeyPath:options:context:3、观察者必须实现 observeValueForKeyPath:ofObject:change:context:方法第一步、确保目标支持 KVO被监测的目标对象的属性支持 KVO 必须满足以下条件:1、目标对象的属性必须支持 KVC,对于 1 对 1 属性简单来说就是实现 set 和 get 方法。详情和 1 对多请阅读官方说明。系统已有类及子类自动支持,放心使用。2、自动和手动属性通知 目标对象必须能发出属性变化通知。系统默认支持,也可自定义。 系统

3、默认支持,且支持的很好,一般无需自定义。/如果需要自定义,需要重新此方法,默认返回 YES+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key;/在 set 方法中手动调用,变化类型只是针对 NSKeyValueChangeSetting- (void)willChangeValueForKey:(NSString *)key;- (void)didChangeValueForKey:(NSString *)key;例如/假设有属性property (nonatomic,copy)NSString *name;+ (BOOL)

4、automaticallyNotifiesObserversForKey:(NSString *)theKey BOOL automatic = NO;/* 只自定义指定属性,其它仍然自动发送通知 */if (theKey isEqualToString:name)/在 set 方法中手动调用相关方法automatic = NO;else/此方法默认返回 YESautomatic = super automaticallyNotifiesObserversForKey:theKey;return automatic;- (void)setName:(NSString *)name/即将变化se

5、lf willChangeValueForKey:name;_name = name; /已经变化self didChangeValueForKey:name;/如果说只有值不相等时才发送通知,提升性能- (void)setName:(NSString *)nameif (!name isEqualToString:_name)self willChangeValueForKey:name;_name = name;self didChangeValueForKey:name;如果涉及 1 对多的容器类,需要自己实现 NSKeyValueChangeInsertion, NSKeyValueC

6、hangeRemoval, NSKeyValueChangeReplacement 三种操作对应的方法,例如/Keys 为属性名称- (void)removeKeysAtIndexes:(NSIndexSet *)indexes self willChange:NSKeyValueChangeRemovalvaluesAtIndexes:indexes forKey:keys;/ Remove the transaction objects at the specified indexes.self didChange:NSKeyValueChangeRemovalvaluesAtIndexe

7、s:indexes forKey:keys;3、属性依赖 如果目标对象属性存在依赖关系,注册合适的依赖 Keys。核心方法为第一种、+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key NS_AVAILABLE(10_5, 2_0);说明:1、返回目标属性依赖属性的 KeyPath 的 Set。当对象注册后,KVO 自动监测该对象所有的KeyPaths。2、其默认实现从对象所属类的方法列表中匹配方法:+keyPathsForValuesAffecting(为属性名,比如 Name) ,如果存在执行并返回结果;如果不存在

8、向底层寻找已经废弃的方法+setKeys:triggerChangeNotificationsForDependentKey:3、可以用来替换手动调用-willChangeValueForKey:/-didChangeValueForKey:来实现属性依赖的解决方案4、不能在已有类的 Category 中使用,在 Category 禁止重写此方法,可以使用+keyPathsForValuesAffecting来实现。第二种、或者重写此格式+keyPathsForValuesAffecting(为属性名,比如 Name)的方法名比如说,姓名=姓+ 名;当二者任一变动时更新姓名property (

9、nonatomic,copy)NSString *name;/姓名property (nonatomic,copy)NSString *firstName;/姓property (nonatomic,copy)NSString *lastName;/名/重新 get 方法,表明字段组成-(NSString *)namereturn NSString stringWithFormat:%,_firstName,_lastName;/通过此方法+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key NSSet *keyPat

10、hs = super keyPathsForValuesAffectingValueForKey:key;if (key isEqualToString:name)NSArray *affectingKeys = lastName, firstName;keyPaths = keyPaths setByAddingObjectsFromArray:affectingKeys;return keyPaths;或者+ (NSSet *)keyPathsForValuesAffectingNamereturn NSSet setWithObjects:lastName, firstName, nil

11、;/改变值- (void)viewDidLoad super viewDidLoad;self setValue:张 forKey:firstName;self setValue:三 forKey:lastName;self addObserver:self forKeyPath:name options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil;/名称改变,刷新姓名self setValue:龙 forKey:lastName;-(void)observeValueForKeyPath:(NSS

12、tring *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)contextNSLog(NSKeyValueChangeOldKey:%,changeNSKeyValueChangeOldKey);NSLog(NSKeyValueChangeNewKey:%,changeNSKeyValueChangeNewKey);/输出结果2016-09-06 17:05:01.904 KVC4192:307124 NSKeyValueChangeOldKey:张三2016-09-06 17:05:01.

13、904 KVC4192:307124 NSKeyValueChangeNewKey:张龙注意:以上关于属性依赖的处理方法不支持一对多的关系。比如说 ViewController 对象有一个 totalNumber 表示总数和属性 datas 数组,数组中 Data 的对象,对象含有 number 属性。/* Data 对象 */interface Data : NSObjectproperty (nonatomic,assign)NSInteger number;end/* ViewController 对象 */interface ViewController ()property (non

14、atomic,assign)NSInteger totalNumber;property (nonatomic,strong)NSArray *datas;end可以采用以下方法解决 1、注册每个 Data 对象的年龄属性为监测属性,ViewController 对象为观察者,data.number变化时,使用集合运算符求和,然后设置 ViewController 的 totalNumber 属性值- (void)viewDidLoad super viewDidLoad;/* 创建 Data 对象 */Data * data1 = Data alloc init;data1.number =

15、 0;Data *data2 = Data alloc init;data2.number = 0;Data *data3 = Data alloc init;data3.number = 0;/* self.datas 属性赋值 */self setValue:data1,data2,data3 forKey:datas;/* 监测 self.datas 中每个 data 对象的 number 属性 */(0, 3) 中 0 表示 index 从 0 开始,0 表示长度 3,也就是 index(0、1、2) ;但是不能使得 self.datas 数组越界NSIndexSet *set = NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 3);self.datas addObserver:self toObjectsAtIndexes:set forKeyPath:number options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil;/* 监测 totalNumber 属性 */self addObserver:self forKeyPath:

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号