KVC

简介

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
// 遍历字典里面所有的key

//  key:name
//  就去模型中查找有没有setName:,直接调用这个对象setName:赋值
//  假如没有找到setName:。就会去模型中查找有没有_name属性,_name = value
//  假如没有找到_name,还会去模型中查找name属性
//  最终没有找到,就会直接报错。
    [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;
}
文章作者: Ammar
文章链接: http://lizhaoloveit.cn/2014/07/20/KVC/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ammar's Blog
打赏
  • 微信
  • 支付宝

评论