字典转模型之KVC和MJExtension底层的实现

一 快速生成@property

1 当我们需要用模型去实现一个比较小的功能的时候,由于我们需要对plist文件进行转化成模型,那么很有可能我们拿到的plist文件中的属性很多,但是我们又因为只需要研究一个很小的功能,那么我们可以不需要将plist文件中的数据全部转化为模型数据,我们只需要提取其中的一部分用来实现模型就可以,那么我们怎么做呢?

2 做法:展开某行,然后拷贝该行的item,然后将所有的item折起来,在将拷贝的东西复制到root上即可直接将一整个plist文件改为自己需要处理的文件,用该文件去处理一项特别小的功能.

3 但是由于plist文件中属性太多,如果我们要创建一个模型,那么不得不写这么多属性,首先写这些属性都是无用功,没什么技术含量,那么我们就想,有没有什么办法,可以一次性生成写好的属性,或者我们直接拷贝就可以了.那么,我们就想到了一个方法,通过一个方法,可以快速的将plist文件中的属性生成@property的格式,我们只需要将结果拷贝,往@interface中粘贴就可以了.

4 代码(通过一个分类就可以达到效果,如果需要就直接将分类拷贝到项目中就可以)

//快速生成@property属性

- (void)creatPropetyCode

{

//创建可变的字符串

NSMutableString*codes = [NSMutableStringstring];

//由于plist文件外层都是字典,那么我们就遍历字典

[selfenumerateKeysAndObjectsUsingBlock:^(id_Nonnull key,id_Nonnull value,BOOL* _Nonnull stop) {

//初始化变量,用来接收字符串的

NSString*code =nil;

//打印所有的value的类型,就知道BOOL到底是什么类型了.

//2016-03-26 23:06:50.867 03-RunTime(字典转模型)[853:40171] __NSCFBoolean

NSLog(@"%@",[value class]);

//判断value的类型,然后响应的凭借出不同类类型的字符串,满足模型中定义属性的需求

if([value isKindOfClass:[NSStringclass]]) {

code = [NSStringstringWithFormat:@"@property (nonatomic, strong) NSString *%@;",key];

}elseif([value isKindOfClass:NSClassFromString(@"__NSCFBoolean")]){

code = [NSStringstringWithFormat:@"@property (nonatomic, strong) BOOL *%@;",key];

}elseif([value isKindOfClass:[NSNumberclass]]){

code = [NSStringstringWithFormat:@"@property (nonatomic, strong) NSNumber *%@;",key];

}elseif([value isKindOfClass:[NSDictionaryclass]]){

code = [NSStringstringWithFormat:@"@property (nonatomic, strong) NSDictionary *%@;",key];

}elseif([value isKindOfClass:[NSArrayclass]]){

code = [NSStringstringWithFormat:@"@property (nonatomic, strong) NSArray *%@;",key];

}

//拼接字符串

[codes appendFormat:@"\n%@\n",code];

}];

//打印出结果

NSLog(@"%@",codes);

}

//从打印的结果来看,大部分的都能打印出来,但是类型是BOOL的却打印不出来,我们也没法通过判断BOOL的类型来打印,因为BOOL就不是一个类.所以我们必须得想法办知道BOOL的类型.


二 KVC底层实现

1 模型中的KVC方法

//KVC

[statusItem setValuesForKeysWithDictionary:dict];


2 问题:KVC底层是怎么实现通过字典对模型中的属性赋值?

2.1 首先我么要明确KVC的使用条件:KVC的使用,必须要保证模型中的属性名要和字典中的key一一对应,否则使用KVC运行时会报错的.

2.2 setValuesForKeysWithDictionary:该方法本质其实就是遍历字典中所有的key,去模型中查找对应的属性,把值给模型属性赋值

3 setValuesForKeysWithDictionary:该方法的底层实现原理:

//遍历

[dict enumerateKeysAndObjectsUsingBlock:^(id_Nonnull key,id_Nonnull obj,BOOL* _Nonnull stop) {

//这行代码才是真正给模型的属性赋值

[s setValue:dict[@"source"] forKey:@"source"];

}];


4 遍历字典的内部给属性赋值遵循下面几点条件

/*

[ssetValue:dict[@"source"]forKey:@"source"];

1.首先会去模型中查找有没有setSource方法,直接调用set方法[ssetSource:dict[@"source"]];

2.去模型中查找有没有source属性,source= dict[@"source"]

3.去模型中查找有没有_source属性,_source= dict[@"source"]

4.调用对象的setValue:forUndefinedKey:直接报错

*/

5 很多时候我们不需要plist文件中的所有的属性都有作用,但是我们又想用kvc来实现给模型属性赋值,那么我们有什么办法呢?

5.1 由于我们都知道,如果在plist文件中的属性和模型中的属性并不是一一对应的关系,但是如果我们用KVC运行起来会直接报错,打印出错误的结果是:setValue: forUndefinedKey:那么我们是不是想办法不让这错误提示出来呢.那么我们可以重写系统的这个方法,里面什么都不需要做.这样同样能达到目的.

-(void)setValue:(id)value forUndefinedKey:(NSString *)key

{



三 MJExtension框架的底层实现(一级转化)

MJ框架与KVC的底层实现不同点:

1 KVC是通过遍历字典中的所有key,然后去模型中寻找对应的属性

2 MJ框架是通过先遍历模型中的属性,然后去字典中寻找对应的key,所以用MJ框架的时候,模型中的属性和字典可以不用一一对应,同样能达到给模型赋值的效果.

3 代码:

//返回一个创建好的模型

+ (instancetype)modelWithDict:(NSDictionary*)dict

{

//创建一个模型

idobjc = [[selfalloc] init];

intcount =0;

/*

方法:获取成员变量列表

参数一:class获取哪个类成员变量列表

参数二:count成员变量总数

*/

//成员变量数组指向数组第0个元素

Ivar *ivarList = class_copyIvarList(self, &count);

//遍历所有成员变量

for(inti =0; i < count; i++) {

//获取成员变量

Ivar ivar = ivarList[i];

//获取成员变量名称(将c转为oc)

NSString*ivarName = [NSStringstringWithUTF8String:ivar_getName(ivar)];

//成员变量名称转换key(将成员变量前边的"_"截取掉)

NSString*key = [ivarName substringFromIndex:1];

//从字典中取出对应value

idvalue = dict[key];

//给模型中属性赋值(底层会去找对应的属性和值)

[objc setValue:value forKey:key];

}

returnobjc;

}

四 附加知识点

1 const与宏的区别

1.1 编译的时刻不一样: 宏:预编译 const:编译

1.2 编译检查:宏不会做编译检查 const会

1.3 宏的好处:宏可以定义函数和方法 const不可以

1.4 宏坏处:大量使用宏,会导致预编译时间过长

2 const作用

2.1 用于修饰右边变量(基本变量,指针变量)

2.2 被const修饰变量只读

2.3 有关const的面试题

int*constp1;// p1:只读*p1:变量

constint*p2;// p2:变量*p2:只读

intconst*p3;// p3:变量*p3:只读

intconst*constp4;// p4:只读*p4:只读

constint*constp5;// p5:只读*p5:只读


3 const在开发当中的使用

3.1 const替换宏,宏:常用字符串或者基本数据定义成宏 -> const

3.2 修饰方法参数,让方法参数只读

4 static和extern

4.1 static:

—–>1> 修饰局部变量,只要被static修饰局部变量,这个局部变量的声明周期就会延长(整个app运行过程中都在),作用域不变

—–>2> 修饰全局变量,只要被static修饰全局变量,这个全局变量只能在当前文件下使用

—–>3> 分配时刻:程序一运行的时候就会分配内存

4.2 extern:

—–>1> 仅仅只用来声明外部全局变量

—–>2> extern不能用来定义变量

5 static和const联合使用

5.1 被static修饰全局变量,全局变量只能在当前文件下使用

5.2 被const修饰,只读.

6 开发中是如何避免重复定义?

做法:只要定义全局变量,都不能再自己的类中定义,一般开发中,我们会搞一个公共的文件来定义全局变量

五 总结

以上就是今天我给大家分享的知识点,很多知识点都写得很详细了,如果有不懂的可以给我留言,谢谢.我明天还会持续更新新的知识点.记得关注哦!!!

Baidu Button BEGIN

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容