标签:oc字典转模型
俺们知道,在iOS开发中,字典是经常出现的一个东东,那么我们直接操作字典呢,很容易产生把眼睛找瞎也找不到的BUG。为什么这么说呢?比如:本身有这么个 tmpDict["name"] 东西,而你却写成了 tmpDict["nane"] ; 这在Xcode中是不会报错的,而你的程序可能就会莫名其妙的崩掉,此时最好的解决方案就是将字典转换成模型。
在使用模型开发时,你一个点语法,点出来的属性,点错了编译器会立刻报错,干掉BUG于摇篮之中~~~~
这里我写了一个分类,主要用于将字典转换成模型:
当然,实现还不够完美~~~哈哈
当字典是这样的时候:
@{ @"name" : @"jack", @"age" : @20, @"height" : @"1.55", @"dog" : @{ @"name" : @"wangcai", @"price" : @"100", @"bone" : @{ @"name" : @"狗骨头", @"weight" : @"200" } }, @"books" : @[ @{ @"name" : @"好书", @"price" : @10000000.6, @"publisher" : @"清华大学出版社", @"author" : @"张宇清" }, @{ @"name" : @"坏书", @"price" : @14.6, @"publisher" : @"北京大学出版社" } ], @"money" : @"100" };
现在我要做的事就是将这些数据全部转换成模型;
NSObject+Extension.h
<span style="font-size:18px;">#import <Foundation/Foundation.h> @interface NSObject (Extension) /** * 假设模型中又数组类型的成员属性,那么传入该数组类型的成员属性名称, 即可得到数组中包含的自定义对象类型 */ - (Class)classForProperty:(NSString *)name; /** * 提供方法,将字典传入进去 */ - (void)setDict:(NSDictionary *)dict; /** * 拿对象来调用该方法,就可将字典转换为模型 */ + (instancetype)objectWithDict:(NSDictionary *)dict; @end </span>
<span style="font-size:18px;">#import "NSObject+Extension.h" #import <objc/runtime.h> #import "Book.h" #import "Dog.h" @implementation NSObject (Extension) - (void)setDict:(NSDictionary *)dict { Class c = self.class; while (c && c != [NSObject class]) { // 用来存储成员变量的数量 unsigned int outCount = 0; // 获得Dog类的所有成员变量 Ivar *ivars = class_copyIvarList(c, &outCount); // 遍历所有的成员变量 for (int i = 0; i<outCount; i++) { // 取出i位置对应的成员变量 Ivar ivar = ivars[i]; NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)]; // 成员变量 --> 属性名 key = [key substringFromIndex:1]; // name, age, books, dog , books // 取出字典值 id value = dict[key]; // 如果是最基本的类型就直接获得,如果是特殊类型,后面会重新赋值 // 字典中没有这个key对应的值 if (value == nil) continue; // 获得成员变量的类型 // @"NSArray", d,i, @"NSString" NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)]; // if ([type isEqualToString:@"@\"Dog\""]) { // value = [Dog objectWithDict:value]; // } NSRange range = [type rangeOfString:@"@"]; if (range.location != NSNotFound) { // 能找到@ type == @"Dog" // 如果都是 @ 开头的数据类型 type = [type substringWithRange:NSMakeRange(2, type.length - 3)]; if (![type hasPrefix:@"NS"]) { // 如果不是NS开头,说明是普通对象类型 // NSString -- Class 通俗的说,这不是继承,而是类包含类 Class class = NSClassFromString(type); value = [class objectWithDict:value]; } /** * 判断NSArray类型 */ if ([type isEqualToString:@"NSArray"]) { // 如果为NSArray类型 NSArray * tmpArr = (NSArray*)value; // 将value强转为NSArray, NSMutableArray * bookArr = [NSMutableArray array]; // 用于保存对象(对象来自于数组中的字典,再一次封装到新数组中) for (int i=0; i< tmpArr.count; i++) { // 遍历数组中字典 NSDictionary * dict = tmpArr[i]; Class clazz = [self classForProperty:key]; // 通过成员变量名获得对应的类字节码类型 if (clazz) { // 判空操作,如果是nil程序会崩溃 id obj = [clazz objectWithDict:dict]; // 获得 [bookArr addObject:obj]; } } value = bookArr; } } // 将字典中的值设置到模型上 [self setValue:value forKeyPath:key]; } free(ivars); c = [c superclass]; // 如果有父类就接着调用 } } + (instancetype)objectWithDict:(NSDictionary *)dict { NSObject *obj = [[self alloc] init]; [obj setDict:dict]; return obj; } @end</span>
标签:oc字典转模型
原文地址:http://blog.csdn.net/u010590318/article/details/44279291