基本原理

利用 runtime 原理,获取模型中所有实例变量列表,根据实例变量以此获取模型中成员变量的名称和属性类型,区分Foundation和自定义属性,需要对NSDictionary和NSArray类型做单独处理。

下面代码是一个简单的原理实现Demo,真正的框架中需要考虑很多问题,例如可以设置只有某个数组中的属性名才允许进行字典和模型的转换,将属性名换为其他key去字典中取值,白名单,黑名单等等设置

+ (instancetype)modelWithDict:(NSDictionary *)dict
{
id objc = [[self alloc] init]; unsigned int count = ; Ivar *ivarList = class_copyIvarList(self, &count); for (int i = ; i < count; i++) { // 实例变量
Ivar ivar = ivarList[i]; // 获取成员属性名
NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)];
NSString *key = [ivarName substringFromIndex:]; id value = dict[key];
if (value == nil) {
continue;
} // 获得成员变量的类型
NSString *ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
NSLog(@"ivar - %@, type - %@", ivarName, ivarType);
ivarType = [ivarType stringByReplacingOccurrencesOfString:@"\"" withString:@""];
ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""]; if ([value isKindOfClass:[NSDictionary class]]) { Class modelClass = NSClassFromString(ivarType);
value = [modelClass modelWithDict:value]; } else if ([value isKindOfClass:[NSArray class]]) { if ([self respondsToSelector:@selector(arrayContainModelClass)]) { NSString *type = [self arrayContainModelClass][key];
Class classModel = NSClassFromString(type);
NSMutableArray *arrM = [NSMutableArray array];
for (NSDictionary *dict in value) {
id model = [classModel modelWithDict:dict];
if (model) {
[arrM addObject:model];
}
} value = arrM;
}
} if (value) {
[objc setValue:value forKey:key];
}
} return objc;
}

常用的 JSON 模型转换库

  • YYModel:支持自动的 JSON/Model 转换,支持定义映射过程。API 简洁,功能也比较简单。
  • JSONModel:一个 JSON 模型转换库,有着比较简洁的接口。Model 需要继承自 JSONModel。
  • Mantle:Github 官方团队开发的 JSON 模型转换库,Model 需要继承自 MTLModel。
  • MJExtension:国内开发者"小码哥"开发的 JSON 模型库,号称性能超过 JSONModel 和 Mantle,使用简单无侵入。

性能、易用性,无浸入性

根据 ibireme 的测试结果:

  • Mantle 在各个测试中,性能都是最差的

  • JSONModel 和 MJExtension 性能相差不多,但都比 Mantle 性能高。

  • YYModel 性能高出其他几个库一个数量级,接近手写代码的效率。

  • YYModel、MJExtension 都是采用 Category 方式来实现功能,比较灵活,无侵入

  • 如果数据量在很小的时候,其实没有可比性的,就好比100ms 和 300ms 的差距,用户是感知不到的,最重要的还是框架的易用性,扩展性,容错性,和无侵入性。

  • 如果对性能、网络流量等有更高的要求,就不要再用 JSON 了,建议改用 protobuf/FlatBuffers 这样的方案。JSON 转换再怎么优化,在性能和流量方面还是远差于二进制格式的。

  • 进行对象类型检查,避免将错误的对象类型赋值到属性,以避免潜在的 Crash 问题。 YYModel 会尝试自动转换,转换失败时留空。对部分对象进行自动转换(比如 NSString 和 NSNumber 之间的转换)

  • 具体容错处理,可能没有框架的设计者有自己不同的考虑,就是想让用户自己去做容错处理。

iOS 字典转模型Model的更多相关文章

  1. IOS 字典快速转换为Model 模型

    一般情况下IOS得局部页面加载的过程是,创建一个Model然后,将Nib文件与Model进行关联,然后能够快速的获取到Nib文件上的控件实例.操作生成页面. 但是原生的内容是没有直接通过Json获取M ...

  2. [iOS基础控件 - 4.2] APP列表 字典转模型Model

    A.使用字典加载数据的缺点 1.用户自行指定key,容易出错 2.存入.取出都需要key,容易混乱   B.模型 (MVC中的model) 1.字典与模型对比: (1)字典:存储数据,通过字符串类型的 ...

  3. iOS字典转模型MJExtension使用

    如果项目是纯OC的建议使用,MJExtension是一套字典和模型之间互相转换的超轻量级框架,可以轻松完成: 字典(JSON) --> 模型(Model) 模型(Model) --> 字典 ...

  4. ios 字典转模型

    <pre name="code" class="objc">#import <Foundation/Foundation.h> @int ...

  5. 字典转模型框架 Mantle的使用:国外程序员最常用的iOS模型

    Mantle简介 Mantle 是iOS和Mac平台下基于Objective-C编写的一个简单高效的模型层框架. Mantle能做什么 Mantle可以轻松把JSON数据.字典(Dictionary) ...

  6. iOS开发——高级技术精选OC篇&Runtime之字典转模型实战

    Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://w ...

  7. IOS 字典模型互转框架 MJExtension

    IOS 字典模型互转框架 MJExtension   能做什么? MJExtension是一套字典和模型之间互相转换的超轻量级框架 MJExtension能完成的功能 字典(JSON) -->  ...

  8. iOS开发——网络篇——JSON和XML,NSJSONSerialization ,NSXMLParser(XML解析器),NSXMLParserDelegate,MJExtension (字典转模型),GDataXML(三方框架解析XML)

    一.JSON 1.JSON简介什么是JSONJSON是一种轻量级的数据格式,一般用于数据交互服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) JSON的格式很像OC中的字典 ...

  9. iOS开发UI篇—字典转模型

    iOS开发UI篇—字典转模型 一.能完成功能的“问题代码” 1.从plist中加载的数据 2.实现的代码 // // LFViewController.m // 03-应用管理 // // Creat ...

随机推荐

  1. Window 下mysql binlog开启及查看,mysqlbinlog

    查看是否开启了binlog: win+r => cmd => 连接mysql=>show variables like 'log_%'; mysql> show variabl ...

  2. java基础 lang包 详细介绍

    Java.javax和org.其中以java开头的包名是JDK的基础语言包,以javax开头的属 (org是organization的简写).而在JDK API中还包含了一些以com.sun开头的包名 ...

  3. PHP设计模式 -- 注册模式

    参考文章:https://segmentfault.com/a/1190000007495855 简介 注册树模式又称注册模式或注册器模式.注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候 ...

  4. 你不知道的JavaScript--Item19 执行上下文(execution context)

    在这篇文章里,我将深入研究JavaScript中最基本的部分--执行上下文(execution context).读完本文后,你应该清楚了解释器做了什么,为什么函数和变量能在声明前使用以及他们的值是如 ...

  5. 你不知道的JavaScript--Item11 arguments对象

    1.什么是arguments arguments 是是JavaScript里的一个内置对象,它很古怪,也经常被人所忽视,但实际上是很重要的.所有主要的js函数库都利用了arguments对象.所以ag ...

  6. 运行yum时出现/var/run/yum.pid已被锁定,PID为xxxx的另一个程序正在运行的问题解决

    出现问题 [root@localhost ~]#yum update 已加载插件: fastestmirror,security /var/run/yum.pid已被锁定,PID为1610的另一个程序 ...

  7. Django—models相关操作

    一.在django后台admin管理页面添加自己增加的表结构 通过终端命令:python3 manage.py makemigrations, python3 manage.py migrate 我们 ...

  8. netty源码分析之揭开reactor线程的面纱(一)

    netty最核心的就是reactor线程,对应项目中使用广泛的NioEventLoop,那么NioEventLoop里面到底在干些什么事?netty是如何保证事件循环的高效轮询和任务的及时执行?又是如 ...

  9. [NOIP2014]飞扬的小鸟 D1 T3 loj2500 洛谷P1941

    分析: 这是一个DP,没什么好说的,细节很烦人. DP[i][j]表示到第i个位置,高度为j点最少的次数. 转移: 当j=m时 k属于[m-h,m]都可以向DP[i][j]转移,即dp[i][j]=m ...

  10. 使用ASIFormDataRequest完成用户的登录操作

    ASIFormDataRequest是用于向表单post数据或get数据,可以用于用户向服务器端发送请求完成登录注册,上传下载数据的操作. 之前写过一篇文章是介绍使用ios内置的功能完成登录操作(NS ...