本章将分为三个部分:

  • KVC是什么
  • KVC之Set/Get
  • KVC键值路径之Set/Get

KVC是什么

KVC,即 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性,并不需要调用setter/getter函数或者类的实例变量。

KVC之Set/Get

类A中有3个变量,都是private权限,关于访问权限的,请参见《Objective-C 成员变量

A.h

@interface A : NSObject
{
@private
NSString *str;
NSInteger value;  //注意这里没星号哦哦哦
NSArray *array;
}
@end

A.m:重写Description函数,用于NSLog

@implementation A
/**
* 重写Description方法,可用于NSLog打印
*/
- (NSString *)description
{
return [NSString stringWithFormat:@"\n%@\n%li\n%@", str, (long)value, array];
}
@end

Main.m:理论上来说,外部变量是访问不到这3个私有变量的,但是暴力的KVC来了。

A *a = [[A alloc] init];

//KVC之set
[a setValue:@"HelloWorld" forKey:@"str"];
[a setValue:@ forKey:@"value"];
[a setValue:@[@"HearthStone", @] forKey:@"array"]; NSLog(@"%@", a); //KVC之get
NSString *str = [a valueForKey:@"str"];
NSInteger value = [[a valueForKey:@"value"] integerValue]; //id 转为 NSInteger
NSArray *array = [a valueForKey:@"array"]; NSLog(@"\n%@\n%ld\n%@", str, (long)value, array);

输出为

HelloWorld
2015
(
HearthStone,
2
)

HelloWorld
2015
(
HearthStone,
2
)

分析:

KVC的Set方法(重点)

[a setValue:@"HelloWorld" forKey:@"str"];

是KVC的set方法,其中key一定要为消息接收者的属性名称,而不能是自定义的。

KVC的Get方法(重点)

NSString *str = [a valueForKey:@"str"];

是KVC的get方法,其中key一定要为消息接收者的属性名称,而不能是自定义的。

当Set方法遇到基本数据类型

[a setValue:@ forKey:@"value"];

NSInteger是基本数据类型,设置基本数据类型的时候,需要将基本类型转化成NSNumber,在设置值的时候,系统会有自动解包的过程,NSNumber会解包赋值给value.

当Get方法遇到基本数据类型

NSInteger value = [[a valueForKey:@"value"] integerValue];  //id 转为 NSInteger

valueForKey返回的是id类型,id转换为NSInteger的方法应该是上面这种,而下面这种写法是错误的!

NSInteger value = (NSInteger)[a valueForKey:@"value"];

题外话:重写Description来方便NSLog的输出

- (NSString *)description
{
return [NSString stringWithFormat:@"\n%@\n%li\n%@", str, (long)value, array];
} NSLog(@"%@", a);

将打印出

HelloWorld
2015
(
HearthStone,
2
)

KVC键值路径之Set/Get

假如A含有一个类B,那么如何通过KVC拿到B的属性呢?答案是使用键值路径。

A.h

@interface A : NSObject
{
@private
NSString *str;
NSInteger value;  //注意这里没星号哦哦哦
NSArray *array;
B *b;
}
@end

B.h

@interface B : NSObject
{
@private
NSinteger *age;
}
@end

现在,假如A的array里面装的都是B(装B--)

Main.m

A *a = [[A alloc] init];
...//set Object
[a setValue:@ forKeyPath:@"b.age"]; NSArray *array = [a valueForKeyPath:@"array.age"]; //返回了数组中所有B的age
NSInteger count = [a valueForKeyPath:@"array.@count"]; //返回了数组中B的个数
NSInteger maxAge = [a valueForKeyPath:@"array.@max.age"]; //返回了数组中B的age最大的
NSInteger sumAge = [a valueForKeyPath:@"array.@sum.age"]; //返回了数组中B的age和
NSInteger avgAge = [a valueForKeyPath:@"array.@avg.age"]; //返回了数组中B的age平均值

键值路径可以用来访问不是基本类型的实例变量的属性,也可以快速取到数组中的对象的同一个属性,同时可以利用@count @max @sum @avg等进行计算。

KVC的键值路径的Set方法(重点)

[a setValue:@ forKeyPath:@"b.age"];

KVC的键值路径的Get方法(重点)

NSArray *array = [a valueForKeyPath:@"array.age"];        //返回了数组中所有B的age

最新文章

  1. Libvlc API 简单说明 [转]
  2. MS SQL执行大脚本文件时,提示“内存不足”的解决办法()
  3. pycharm常用快捷键总结
  4. 在 .NET 4.5 中反射机制的变更
  5. codeforces C1. The Great Julya Calendar 解题报告
  6. 64位WIN7+oracle11g+plsql安装
  7. Jquery easyui datagrid 导出Excel
  8. 探索VS中C++多态实现原理
  9. AS问题解决系列3—iCCP: Not recognizing known sRGB profile
  10. javascript笔记09:javascript的下拉式导航菜单
  11. FreeBSD 安装axel提高ports的安装速度
  12. UIViewController控制器的生命周期
  13. 不显示BOM清单的版本
  14. poj2509---抽k根烟就换一支,求能抽烟的总数
  15. 基于visual Studio2013解决算法导论之042单源最短路径
  16. java连接mysql以及增删改查操作
  17. [BZOJ]2594 水管局长数据加强版(Wc2006)
  18. cassandra eclipse 环境构建
  19. cmd登录系统用户
  20. GlusterFS 安装 on centos7

热门文章

  1. Spring中bean的生命周期!
  2. 公司交换机arp 绑定操作
  3. Java中Math类的几个四舍五入方法的区别
  4. Redis总结(二)C#中如何使用redis(转载)
  5. sysbench的安装详解
  6. Mysql主从同步(1)-主从/主主环境部署梳理
  7. Java运行Python脚本的几种方式
  8. atitit,it人怎么样才容易事业成功?? 有以下五种性格的人容易成功
  9. js控制伪元素样式
  10. linux下挂载win7的共享文件夹