面向对象3
来源:互联网 发布:linux环境高级编程 编辑:程序博客网 时间:2024/04/29 10:49
键值编码(KVC)和键值监听(KVO)
KVC
@interface MyUser:NSObject@property (nonatomic, copy) NSString* name;@endmain(){ @autoreleasepool { MyUser* user = [[MyUser allopc] init]; //用KVC方式为属性赋值 [user setValue:@"孙悟空" forKey:@"name"]; //用KVC方式获取属性值 NSLog(@"user's name is: %@", [user valueForKey:@"name"]); }}
KVC两种方法:
- setValue:属性值 forKey:属性名 : 用于赋值
- valueForKey:属性名 : 获取属性值
处理不存在的key
当key不存在时,会自动调用 setValue:forUndefinedKey: 和 valueForUndefinedKey: 由于这两个方法默认的方法体会引发 ‘NSUnknownKeyException’ 异常,并结束程序,一般情况下需要重写这两个方法。
- (void) setValue: (id) value forUndefinedKey: (id) key{ NSLog(@"the key: (%@) being set does not exist!", key); NSlog(@"the value being set is: %@", value);}- (void) valueForUndefinedKey: (id) key{ NSLog(@"the key: (%@) being get does exist!", key);}
处理nil值
非chat、NSString*类型的属性,不能赋予 nil ,可通过重写 NSObject 的 setNilValueForKey: 方法来将不合理的 nil 转化成合理的其他值
//省略代码:定义类接口和实现部分,分别呢含有 NSString* name 和 int price 属性,并为两个属性赋值 nil//一下为重写 NSObject 的setNilValueForKey: 方法- (void) setNilValueForKey: (id) key{ //当尝试为 price 属性赋值 nil 时,执行以下语句 if([key isEqualToString:@"price"]) { //将 price 赋值为0 price = 0; } else { //调回父类的 setNilValueForKey: 方法来赋值 nil [super setNilValueForKey: key]; }}
Key路径
KVC可对复合属性进行操作,所谓复合属性即:将已存在的类A作为本类B的属性,这样在本类B中亦可调用属性类A的属性(B.A.property)
#import <Foundation/Foundation.h>#import "MyItem.h"@interface MyItem: NSObject@property NSString* name;@property int price;@end@interface MyOrder: NSObject//将 MyItem* 类对象作为属性@property MyItem* item;@end//实现部分忽略,自行编写int main(int argh, char * argv[]){ @autoreleasepool { //创建MyOrder对象 MyOrder* order = [[MyOrder alloc] init]; //用KVC方式赋值 [order setValue:[[MyItem alloc] init] forKey:@"item"]; [order setValue:@"张三" forKey:@"item.name"]; [roder setValue:[NSNumber numberWithInt:25] forKey:@"item.price"]; //用KVC方式访问属性值 NSLog(@"name is: %@",[order calueForKey:@"item.name"]); }}
键值监听(KVO)
应用场景:数据模型组件中有数据发生修改,需视图组件实时更新
- addObserver:forKeyPath:options:context: 注册监听器
- removeObserver:forKeyPath: 删除监听器
- removeObserver:foKea:contact: 删除监听器
//接口部分省略,自行编写@implementation MyItemView@snythesize item = _item;- (void) setItem:(MyItem*) item //自定义 setItem: 方法{ self->_item = item; //为item添加监听器,监听 name 属性, item为类属性,name为复合属性 [self.item addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew Context:nil];}//重写 observerValueForKeyPath: 方法,这样监听的数据模型发生改变时,就会回调监听器的该方法- (void) observerValueForKeyPath:(NSString*) keyPath ofObject:(id) object chat:(NSDictionary*) change context:(void*)context{ NSLog(@"--调用了 observerValueForKeyPath: 方法--"); NSLog(@"对象(%@)的属性(%@)被修改为 %@,被修改的上下文是 %@",object, keyPath, [hange objectForKey:@"new"], context);}- (void) dealloc{ //删除监听器 [self.item removeObserver:self forKeyPath:@"name"];}@end
调用代码:
MyItem* item = [[MyItem alloc] init];item.name = @"张三"; //由于视图组件没有创建对象,所以不会显示信息MyItemView* itemView = [[MyItemView alloc] init];[itemView showItemInfo]; //showItemInfo为输出信息方法,之前代码中省略掉了item.name = @"李四"; //视图组件已创建对象,name属性被监听且值被更改,激发了监听器会输出结果
输出结果:
item name is: 张三--调用了observerValueForKeyPath: 方法--对象(<MyItem: 0x7faa02309780>)的属性(name)被修改为 李四,被修改的上下文是 (null)
0 0
- 面向对象3原则
- C#面向对象3
- 面向对象3
- 面向对象基本3
- java面向对象3
- 面向对象总结3
- 面向对象基础3
- 面向对象3
- 面向对象(3)
- 面向对象3
- 面向对象3
- 面向对象(3)
- java--面向对象3
- 面向对象(3)
- 面向对象3
- 面向对象2(3)
- java面向对象3
- javaday08-面向对象3
- AngularJS 源码分析3
- AngularJS 源码分析4
- 最常用的15大Eclipse开发快捷键技巧
- Linux下修复“fatal error: jsoncpp/json/json.h: No such file or directory” 分类: C++ | 标签: Linux,jsonjson
- Servlet跳转
- 面向对象3
- 个人心记
- 2015-2016年第一学期第一周协会活动 二分搜索
- hadoopSSH无密码登录
- C++的Json解析库:jsoncpp和boost .
- 清除浮动的几种方式
- Toast.makeText
- 关于block使用的5点注意事项
- android graphic(7)—gralloc分配图形缓冲区