本文详细介绍在iOS开发中对KVC使用的一些心得体会,希望对阅读者有帮助,如有疏漏之处望指正,谢列位看官。
1.利用KVC给模型属性赋值用 [model setValuesForKeysWithDictionary:dict]
+ (instancetype)statusWithDict:(NSDictionary *)dict {id obj = [[self alloc] init];[obj setValuesForKeysWithDictionary:dict];return obj;}
(1)这个方法的底层通过调用 enumerateKeysAndObjectsUsingBlock: 一个个地取出字典当中的key,判
断调用对象model 有没有setKey(就是看调用对象有没有这个属性的set方法)通过respondsToSelector:
判断,如果有,直接在set方法中将value赋值给属性
(2)如果没有,看有没有带下划线的成员变量 _key,如果有,直接进行赋值
(3)如果没有,看有没有不带下划线的成员变量 key,如果有,直接进行赋值
(4)都没有,表示在对象当中没有找到对应的成员变量,会报错
2.两个使用前提:
(1)字典中的键名必须要和模型中的属性名都保持一致
(2)保证模型中的属性个数不能少于字典中的键值对的个数,如果字典中的键值对个数多于模型的属性个数,重写setValueforUndefinedKey:
3.使用场景
(1)赋值 setValue: forKeyPath:
相比 setValue: forKey: 可以通过路径取值,赋值
Person *p = [[Person alloc] init];Dog *dog = [[Dog alloc] init];p.dog = dog;p.name = @"张三";p.age = 18;NSLog(@"%@-----%d",p.name, p.age);// 1.kvc的赋值[p setValue:@"李四" forKeyPath:@"name"];[p setValue:@"20" forKeyPath:@"age"];[p setValue:@"旺财" forKeyPath:@"dog.name"];NSLog(@"%@-----%d------%@",p.name, p.age,dog.name);
(2)取值 valueForKeyPath:
// 2.kvc的取值 能够一次拿到所有对象的同一个属性Person *p1 = [[Person alloc] init];p1.name = @"a";p1.age = 18;Person *p2 = [[Person alloc] init];p2.name = @"b";p2.age = 19;Person *p3 = [[Person alloc] init];p3.name = @"c";p3.age = 20;NSArray *persons = @[p1, p2, p3];NSLog(@"%@",[persons valueForKeyPath:@"p1.age"]);// NSLog(@"%@-----%d",[p valueForKeyPath:@"name"],[[p valueForKeyPath:@"age"] intValue]);
(3)模型转字典 dictionaryWithValuesForKeys:
// 3.模型转字典Person *p = [[Person alloc] init];p.name = @"tom";p.age = 18;NSDictionary *dict = [p dictionaryWithValuesForKeys:@[@"name",@"age"]];NSLog(@"%@",dict);
属性较多的处理方式:
#import <objc/runtime.h> 运行时的框架//把自定义对象的数组,所有的对象都转换成字典NSMutableArray *mArray = [NSMutableArray arrayWithCapacity:2];for (HMVideo *video in array){// 以下为改良代码***********************************unsigned int iCount = 0;// unsigned int pCount = 0;Ivar *iList = class_copyIvarList([HMVideo class], &iCount);NSLog(@"成员变量数量%u", iCount);// NSLog(@"属性数量%u", pCount);NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:iCount];// 遍历数组for (int i = 0; i < iCount; i++){// 成员变量名称const char *name = ivar_getName(iList[i]);[arrayM addObject:[NSString stringWithUTF8String:name]];}NSLog(@"------------>%@", arrayM);// 释放对象free(iList);NSDictionary *dic = [video dictionaryWithValuesForKeys:arrayM];[mArray addObject:dic];}NSData *data = [NSJSONSerialization dataWithJSONObject:mArray options:0 error:NULL];[self postJSON:data];
(4)字典转模型 setValuesForKeysWithDictionary:
4.如果解析网络数据之后的字典中有一部分键值模型中不需要,可以重写
- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
5.解析之后的字典中有键值为id ,可以使用KVC进行赋值
6.解析之后的字典中的键值有int等数据类型关键字处理方式:
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{if ([key isEqualToString:@"int"]) {self.intxxx = value;}}
7.KVC的方法是 NSObject的方法 写在(NSKeyValueCoding)分类中
8.多重模型的嵌套
- (void)setValue:(id)value forKey:(NSString *)key {// 判断 key 是否是 userif ([key isEqualToString:@"user"]) {self.user = [HMUser userWithDict:value];return;}// 判断 key 是否是 retweeted_statusif ([key isEqualToString:@"retweeted_status"]) {self.retweeted_status = [HMStatus statusWithDict:value];return;}// 判断 key 是否是 pic_urlsif ([key isEqualToString:@"pic_urls"]) {NSMutableArray *urls = [NSMutableArray array];// 遍历数组,生成 url 数组for (NSDictionary *dict in value) {[urls addObject:[NSURL URLWithString:dict[@"thumbnail_pic"]]];}self.pic_urls = urls.copy;return;}!!![super setValue:value forKey:key];
}
394

被折叠的 条评论
为什么被折叠?



