首页 > 学院 > 开发设计 > 正文

利用runTime,实现以模型为主的字典转模型(注意与KVC的区别)

2019-11-14 20:28:40
字体:
来源:转载
供稿:网友

  将字典转化为模型,面向模型开发,是在开发中最为常用的功能。利用KVC可以将字典转换为模型,但是前提有三个约束,一个是必须保证模型的属性个数大于等于字典个数,二是属性名称与字典的key必须相同,三是对于模型中的基本数据类型无法转换。

  其中第一条与第三条,是其最大的弊端。例如,如果从服务器获取的数据字典,并不想使用所有的键值对。但是在开发中还是必须得全部将对应属性列出,全部进行转换(除非你一个一个写,不使用KVC)。

  下面的代码就可以解决上述问题:实现以模型为主,将字典数据进行部分转化,并识别基本数据类型。约束仅仅是要求模型属性名称与字典KEY保持一致(因为底层还是使用KVC);

 1 // 2 //  NSObject+Value.m 3 // 4 //  Created by shunzi 5-10-2014. 5 //  Copyright (c) 2014年 shunzi. All rights reserved. 6 // 7  8 #import "NSObject+Value.h" 9 #import <objc/message.h>10 #import <objc/runtime.h>11 12 @implementation NSObject (Value)13 - (void)setValues:(NSDictionary *)values14 {15     Class c = [self class];16     17     while (c) {18         // 1.获得所有的成员变量19         unsigned int outCount = 0;20         Ivar *ivars = class_copyIvarList(c, &outCount);21 22         for (int i = 0; i<outCount; i++) {23             Ivar ivar = ivars[i];24             25             // 2.属性名26             NSMutableString *name = [NSMutableString stringWithUTF8String:ivar_getName(ivar)];27             28             // 删除最前面的_29             [name replaceCharactersInRange:NSMakeRange(0, 1) withString:@""];30             31             // 3.取出属性值32             NSString *key = name;33             if ([key isEqualToString:@"desc"]) {34                 key = @"description";35             }36             if ([key isEqualToString:@"ID"]) {37                 key = @"id";38             }39             id value = values[key];40             if (!value) continue;41             42             // 4.SEL43             // 首字母44             NSString *cap = [name substringToIndex:1];45             // 变大写46             cap = cap.uppercaseString;47             // 将大写字母调换掉原首字母48             [name replaceCharactersInRange:NSMakeRange(0, 1) withString:cap];49             // 拼接set50             [name insertString:@"set" atIndex:0];51             // 拼接冒号:52             [name appendString:@":"];53             SEL selector = NSSelectorFromString(name);54             55             // 5.属性类型56             NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];57             58             if ([type hasprefix:@"@"]) { // 对象类型59                 objc_msgSend(self, selector, value);60             } else  { // 非对象类型61                 if ([type isEqualToString:@"d"]) {62                     objc_msgSend(self, selector, [value doubleValue]);63                 } else if ([type isEqualToString:@"f"]) {64                     objc_msgSend(self, selector, [value floatValue]);65                 } else if ([type isEqualToString:@"i"]) { 66                     objc_msgSend(self, selector, [value intValue]);67                 }  else { 68                     objc_msgSend(self, selector, [value longLongValue]);69                 }70             }71         }72         73         c = class_getSuperclass(c);74     }75 }76 @end

 头文件仅仅包含对此方法的声明,所以不在此粘贴


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表