OC——关于KVC
我们知道在C#中可以通过反射读写一个对象的属性,有时候这种方式特别方便,因为你可以利用字符串的方式去动态控制一个对象。其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的动态读写,这种方式就是Key Value Coding(简称KVC)。
KVC的操作方法由NSKeyValueCoding协议提供,而NSObject就实现了这个协议,也就是说ObjC中几乎所有的对象都支持KVC操作,常用的KVC操作方法如下:
- 动态设置: setValue:属性值 forKey:属性名(用于简单路径)、setValue:属性值 forKeyPath:属性路径(用于复合路径,例如Person有一个Account类型的属性,那么person.account就是一个复合属性)
- 动态读取: valueForKey:属性名 、valueForKeyPath:属性名(用于复合路径)
Person *person1=[[Person alloc]init];
//动态设置
[person1 setValue:@"" forKey:@"name"];//简单路径
[person1 setValue:@100000000.0 forKeyPath:@"account.balance"];//复合路径 //动态读取
[person1 valueForKey:@"name" ]//简单路径
[person1 valueForKeyPath:@"account.balance"]//复合路径
注:即便对象属性是非字符串你依然可以使用字符串赋值,KVC就是这么霸气。。
从Dictionary来生成对象
setValuesForKeysWithDictionary, 会为我们把和dictionary的key名字相同的class proerty设置上dict中key对应的value,请注意,你的Dictionary的Key一定一定要和你的类的属性名完全一致。
-(id) initWithDictionary:(NSMutableDictionary*) jsonObject
{
if((self = [super init]))
{
[self init];
[self setValuesForKeysWithDictionary:jsonObject];
}
return self;
}
如果真的有一些特殊情况使你的Dictionary和你的类的属性肯定有不一样的属性名,那么我们可以重写setValue:(id)value forUndefinedKey:(NSString *)key 方法
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
if([key isEqualToString:@"nameXXX"])
self.name = value;
if([key isEqualToString:@"ageXXX"])
self.age = value;
else
[super setValue:value forKey:key];
}
所以只要重载这个方法,就可以处理了那些无法跟property相匹配的key了,默认的实现是抛出一个NSUndefinedKeyException
如果 这时候server返回的People有了内嵌的json(如Products{product1{count:xx, sumPrice:xx}}, product2{} ….),又该怎么办,能把这个内嵌的json转化成我们的客户端的Product类嘛, 当然可以这时候就需要重载setValue:forKey, 单独处理”Products”这个key, 把它wrapper成我们需要的class
-(void) setValue:(id)value forKey:(NSString *)key
{
if([key isEqualToString:@"products"])
{
for(NSMutableDictionary *productDict in value)
{
Prodcut *product = [[Product alloc] initWithDictionary:prodcutDict];
[self.products addObject:product];
}
}
}
一些其他的使用场景
[array valueForKeyPath:@"name.capitalizedString"]
最新文章
- selenium+python+eclipse开发中遇到的问题
- jquery autocomplete实现读取sql数据库自动补全TextBox
- Windows系统时间同步出错解决办法
- Dapper.NET - ORM(ibatis.Net)
- 【nodejs】创建udp套接字的类型参数的含义
- Android 静默安装/后台安装
- ZOJ 3607贪心算法
- 3.1.2 MVC模式和URL访问
- thunk技术
- 简单分析beyond作曲
- nodejs 文件读取一行
- 树的三种遍历方式(C语言实现)
- 【adb】连接BlueStacks
- 用mapreduce 处理气象数据集
- python nmap
- sklearn—特征工程
- HDU 4612 Warm up (边双连通分量+缩点+树的直径)
- js数字转换成财务金额
- 【TP3.2 + 其他任何PHP框架】编辑、删除、添加数据,返回原分页 (ajax+form两种方式提交均可以)
- ubuntu 镜像站部署
热门文章
- 图解如何安装MySQL5.0
- C#使用Xamarin开发可移植移动应用进阶篇(7.使用布局渲染器,修改默认布局),附源码
- View.post() 不靠谱的地方你知道吗?
- SourceTree 简单使用 for Mac
- python基础教程(五)
- [2012-08-21]FreeBSD9.0体验记
- carry-检查数据接口返回数据合法性
- MySQL视图view/存储过程和函数的使用
- Centos 6系统修复grub
- 【JavaScript基础系列】决定你的人生能走多远的,是基础。