简介
KVC是KeyValue Coding的简称,它是一种可以直接通过字符串 key 来访问类属性的机制。而不是通过调用Setter、Getter方法访问。
当使用KVO、Core Data、CocoaBindings、AppleScript(Mac支持)时,KVC是关键技术。
KVC 关键方法定义在:NSKeyValueCodingprotocol
1 2 3 4
| - (id)valueForKey:(NSString *)key; - (void)setValue:(id)value forKey:(NSString *)key; - (id)valueForKeyPath:(NSString *)keyPath; - (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
|
前两个直接传入“属性名”,后两个需要传入属性路径NSString“xx.xx”形式。
KVC 最常见的作用是给模型属性赋值。
底层实现原理:
代码实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
[dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { NSString *funcName = [NSString stringWithFormat:@"set%@",key.capitalizedString]; NSString *funcName2 = [NSString stringWithFormat:@"_%@", key]; if ([flag respondsToSelector:NSSelectorFromString(funcName)]) { [flag setValue:obj forKeyPath:key]; } else if ([self getVariableWithClass:self varName:funcName2]) { [flag setValue:obj forKey:key]; } else if ([self getVariableWithClass:self varName:key]) { [flag setValue:obj forKey:key]; } }]; [flag setValuesForKeysWithDictionary:dict];
|
上述例子中, getVariableWithClass:
是一个类方法用于判断一个类中是否包含哪个属性
判断一个类中是否包含某个属性,YES包含,NO不包含。 (给NSObject写一个分类)
把一些通用的方法抽离出来可以让程序更加简洁
1 2 3 4 5 6 7 8 9 10 11 12
| + (BOOL) getVariableWithClass:(Class) myClass varName:(NSString *)name{ unsigned int outCount, i; Ivar *ivars = class_copyIvarList(myClass, &outCount); for (i = 0; i < outCount; i++) { Ivar property = ivars[i]; NSString *keyName = [NSString stringWithCString:ivar_getName(property) encoding:NSUTF8StringEncoding]; keyName = [keyName stringByReplacingOccurrencesOfString:@"_" withString:@""]; if ([keyName isEqualToString:name]) { return YES; } } return NO; }
|