在开发中,对于处理网络请求中获取的数据(即把请求到的json或字典转换成方便使用的数据模型)是我们在开发中必不可少的操作。诸如强大的第三方MJExtension、JSONModel或者YYModel是我们所熟知的框架,因为它们使用起来简单方便,简单到有时候一句代码就可以实现我们所需要的字典和模型之间的转换。但我们不能光会用,也要明白它们实现的原理。今天我介绍下基本原理 相信大家理解原理基本也可以自己写一个。
首先我们需要了解runtime获取成员变量:
unsigned int count;//成员变量的数量
//获取成员变量元素的数组
Ivar *ivars = class_copyIvarList([LsPerson class], &count);
for (int i = 0; i < count; i++) {
// 取出i位置的成员变量
Ivar ivar = ivars[I];
NSLog(@" %s", ivar_getName(ivar));
//获取成员变量的名称
ivar_getName
}
开干直接上码
@interface NSObject (Json)
/**
字典转模型
@param json jsondict
@param dict 这里面是需要改变名字的字典 key是转换后的名称 value是转换后的
@return ——
*/
+ (instancetype)ls_objectWithJson:(NSDictionary *)json proDict:(NSDictionary *)dict;
#import "NSObject+Json.h"
#import <objc/runtime.h>
@implementation NSObject (Json)
+ (instancetype)ls_objectWithJson:(NSDictionary *)json proDict:(NSDictionary *)dict
{
id obj = [[self alloc] init];
unsigned int count;
//获取我所有成员变量的信息
Ivar *ivars = class_copyIvarList(self, &count);
for (int i = 0; i < count; i++) {
// 取出i位置的成员变量
Ivar ivar = ivars[I];
NSMutableString *name = [NSMutableString stringWithUTF8String:ivar_getName(ivar)];
//去掉下划线
[name deleteCharactersInRange:NSMakeRange(0, 1)];
// 设值
id value = json[name];
NSArray *keyArray = dict.allKeys;
//判断有没有要改变名字的然后改变
for (NSString *keyStr in keyArray) {
if ([name isEqualToString:keyStr]) {
NSString *valueStr = dict[keyStr];
value = json[valueStr];
}
}
//这里最好加一个 @try 因为value为空时会崩溃
@try {
[obj setValue:value forKey:name];
} @catch (NSException *exception) {
} @finally {
}
}
free(ivars);//释放
return obj;
}
搞懂了上面然后就是是数组字典转数组模型
/**
数组字典转数组模型
@param array 数组字典
@param dict 这里面是需要改变名字的字典 key是转换后的名称 value是转换后的
@return 数组
*/
+(NSArray *)ls_arrayWithJson:(NSArray *)array proDict:(NSDictionary *)dict;
/**
数组字典转数组模型
@param array 数组字典
@param dict 这里面是需要改变名字的字典 key是转换后的名称 value是转换后的
@return 数组
*/
+(NSArray *)ls_arrayWithJson:(NSArray *)array proDict:(NSDictionary *)dict{
NSMutableArray *arrayDataSoure = [[NSMutableArray alloc]init];
for (NSDictionary *jsonDict in array) {
id obj = [[self alloc]init];
unsigned int count;
//获取我所有成员变量的信息
Ivar *ivars = class_copyIvarList(self, &count);
for (int i = 0; i<count; i++) {
Ivar ivar = ivars[I];
// 取出i位置的成员变量
NSMutableString *name = [NSMutableString stringWithUTF8String:ivar_getName(ivar)];
[name deleteCharactersInRange:NSMakeRange(0, 1)];
id value = jsonDict[name]; // 设值
NSArray *keyArray = dict.allKeys;
//判断有没有要改变名字的然后改变
for (NSString *keyStr in keyArray) {
if ([name isEqualToString:keyStr]) {
NSString *valueStr = dict[keyStr];
value = jsonDict[valueStr];
}
}
//这里最好加一个 @try 因为value为空时会崩溃
@try {
[obj setValue:value forKey:name];
} @catch (NSException *exception) {
} @finally {
}
}
[arrayDataSoure addObject:obj];
}
return arrayDataSoure;
}
然后在外部调用
// 字典转模型
NSDictionary *json = @{
@"id" : @30,
@"age" : @40,
@"weight" : @70,
@"name" : @"Jack",
@"height" : @"170cm"
};
LSperson *person = [LSperson ls_objectWithJson:json proDict:@{@"ID":@"id",@"heightStr":@"height"}];
NSArray *dataSoure = [LSperson ls_arrayWithJson:@[json,json,json] proDict:@{@"ID":@"id"}];
打印看看:
WeChatcecf975bdd99ce75aa29f8bd64a89883.png
对吧这样就转换过来了。
其实原理很简单,只是很多复杂的我们要考虑很多细节。只要知道原理了细节就慢慢摸索吧