本章将分为三个部分:
- 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:@" %@ %li %@", str, (long)value, array]; } @end
Main.m:理论上来说,外部变量是访问不到这3个私有变量的,但是暴力的KVC来了。
A *a = [[A alloc] init]; //KVC之set [a setValue:@"HelloWorld" forKey:@"str"]; [a setValue:@2015 forKey:@"value"]; [a setValue:@[@"HearthStone", @2] 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(@" %@ %ld %@", 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:@2015 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:@" %@ %li %@", 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:@23 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:@23 forKeyPath:@"b.age"];
KVC的键值路径的Get方法(重点)
NSArray *array = [a valueForKeyPath:@"array.age"]; //返回了数组中所有B的age