KVC简介
全称是Key-value coding,翻译成键值编码。它提供了一种使用字符串而不是访问器方法去访问一个对象实例变量的机制。
KVC用法
- (id)valueForKey:(NSString *)key;
- (void)setValue:(id)value forKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
Key与KeyPath
Key较容易理解,就是要访问的属性名称对应的字符串。
KeyPath是一个被点操作符隔开的用于访问对象的指定属性的字符串序列。
即通过KeyPath可以访问属性的属性,比如KeyPath "address.street"将会访问消息接收对象所包含的address属性中包含的一个street属性。其实KeyPath说白了就是我们平时使用点语法访问某个对象的属性时所写的那个字符串。
点语法与KVC
在实现了访问器方法的类中,使用点语法和KVC访问对象其实差别不大,二者可以任意混用。但是没有访问起方法的类中,点语法无法使用,这时KVC就有优势了。
KVC对数值和结构体型属性的支持
KVC可以自动的将数值或结构体型的数据打包或解包成NSNumber或NSValue对象,以达到适配的目的。
- 数值类型转为NSNumber对象
+ (NSNumber *)numberWithChar:(char)value;
+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
+ (NSNumber *)numberWithShort:(short)value;
+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
+ (NSNumber *)numberWithInt:(int)value;
+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
+ (NSNumber *)numberWithLong:(long)value;
+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
+ (NSNumber *)numberWithLongLong:(long long)value;
+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
+ (NSNumber *)numberWithFloat:(float)value;
+ (NSNumber *)numberWithDouble:(double)value;
+ (NSNumber *)numberWithBool:(BOOL)value;
+ (NSNumber *)numberWithInteger:(NSInteger)value NS_AVAILABLE(10_5, 2_0);
+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value NS_AVAILABLE(10_5, 2_0);
- 基本结构类型转为NSValue
+ (NSValue *)valueWithCGPoint:(CGPoint)point;
+ (NSValue *)valueWithCGSize:(CGSize)size;
+ (NSValue *)valueWithCGRect:(CGRect)rect;
+ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform;
+ (NSValue *)valueWithUIEdgeInsets:(UIEdgeInsets)insets;
+ (NSValue *)valueWithUIOffset:(UIOffset)insets NS_AVAILABLE_IOS(5_0);
- 自定义结构类型转为NSValue
//将int转成NSValue
NSValue *value = [NSValue valueWithBytes:&result objCType:@encode(int)];
//将NSValue转成int
[value getValue:&result];
KVC相关集合运算符
集合运算符是一个特殊的Key Path,可以作为参数传递给valueForKeyPath:方法,注意只能是这个方法,如果传给了valueForKey:方法则会崩溃。
运算符是一个以@开头的特殊字符串,格式如下图所示:
简单集合运算符
简单集合运算符共有@avg,@count,@max,@min,@sum5种,目前还不支持自定义。
举例说明,要获取amount的平均值可以这样:
NSNumber *transactionAverage = [transactions valueForKeyPath:@"@avg.amount"];
对象运算符
比集合运算符稍微复杂,能以数组的方式返回指定的内容,一共有两种:
@distinctUnionOfObjects
@unionOfObjects
区别是前者返回的元素都是唯一的,是去重以后的结果;后者返回的元素是全集。
KVC如何访问属性值
KVC再某种程度上提供了访问器的替代方案。不过访问器方法是一个很好的东西,以至于只要是有可能,KVC也尽量再访问器方法的帮助下工作。
为了设置或者返回对象属性,KVC按顺序使用如下技术:
- 检查是否存在-<key>、-is<key>(只针对布尔值有效)或者-get<key>的访问器方法,如果有可能,就是用这些方法返回值;
检查是否存在名为-set<key>:的方法,并使用它做设置值。对于-get<key>和-set<key>:方法,将大写Key字符串的第一个字母,并与Cocoa的方法命名保持一致; - 如果上述方法不可用,则检查名为-_<key>、-_is<key>(只针对布尔值有效)、-_get<key>和-_set<key>:方法;
- 如果没有找到访问器方法,可以尝试直接访问实例变量。实例变量可以是名为:<key>或_<key>;
- 如果仍为找到,则调用valueForUndefinedKey:和setValue:forUndefinedKey:方法。这些方法的默认实现都是抛出异常,我们可以根据需要重写它们。