JSONModel

JSONModel源码 JSONModelClassProperty: 封装的jsonmodel的一个属性,它包含了对应属性的名字(name:sex),类型(type:NSString),是否是JSONModel支持的类型(isStandardJSONType:YES/NO),是否是可变对象(isMutable:YES/NO)等属性。其中对于protocol的使用较为特殊,在这里的protocol并非我们平常当作接口抽象的作用,而是单纯的为了让encode string中增加相应的字段,可以在解析与赋值的时候给予特定的含义。 阅读详情
每个IOS开发人员对于JSONModel都是应该比较熟悉的,这次达内科技的金牌讲师就打算专门谈谈它,掌握这个JSONModel对于ios培训的同学们来说是举足轻重的。
  JSONModel是一个解析服务器返回的Json数据的库。
  通常服务器传回的json数据要通过写一个数据转换模块将NSDictionary转换为Model,将NSString数据转换为Model中property的数据类型。
  这样服务器如果要做修改,可能需要改两三个文件。
  JSONModel的出现就是为了将这种解析工作在设计层面完成。
  对其源码的核心部分JSONModel.m做了源码阅读,笔记如下:
  在
  -(id)initWithDictionary:(NSDictionary*)dicterror:(NSError**)err
  函数中完成所有解析工作:如果有任何失误或者错误直接返回nil。
  -(id)initWithDictionary:(NSDictionary*)dicterror:(NSError**)err
  {
  //1、做有效性判断(dict是不是空啊,dict是不是真是一个NSDictionary)
  //checkfornilinput
  if(!dict){
  if(err)*err=[JSONModelErrorerrorInputIsNil];
  returnnil;
  }
  //invalidinput,justcreateemptyinstance
  if(![dictisKindOfClass:[NSDictionaryclass]]){
  if(err)*err=[JSONModelErrorerrorInvalidData];
  returnnil;
  }
  //createaclassinstance
  self=[superinit];
  if(!self){
  //superinitdidn'tsucceed
  if(err)*err=[JSONModelErrorerrorModelIsInvalid];
  returnnil;
  }
  //__setup__中通过调用__restrospectProperties建立类属性的映射表,并且存放在全局变量classProperties里面
  //->__restrospectProperties中利用runtimefunction搞出属性列表:
  //->获得属性列表class_copyPropertyList(得到objc_property_t数组)->对于每一个objc_property_t调用property_getName获得名称,property_getAttributes获得属性的描述(字符串)->通过解析字符串获得属性的类型、是否是Mutable、是否是基本的JSON类型等等
  //->调用[classsuperclass]获得父类继续获取列表
  //->列表保存在classProperties中备用
  //->调用+keyMapper获得key转换列表,生成JSONKeyMapper对象存入keyMapper。
  //doinitialclasssetup,retrospecproperties
  [self__setup__];
  //看看必传参数中是否在输入参数中都有。
  //checkifallrequiredpropertiesarepresent
  NSArray*incomingKeysArray=[dictallKeys];
  NSMutableSet*requiredProperties=[self__requiredPropertyNames];
  NSSet*incomingKeys=[NSSetsetWithArray:incomingKeysArray];
  //getthekeymapper
  JSONKeyMapper*keyMapper=keyMappers[__className_];
  //transformthekeynames,ifneccessary
  if(keyMapper){
  //对比dict输入的keyName导入NSSet与keyMapper中JSONKeyMapper对象做keyName的转换。统一转换为对象的propertyname。
  NSMutableSet*transformedIncomingKeys=[NSMutableSetsetWithCapacity:requiredProperties.count];
  NSString*transformedName=nil;
  //loopovertherequiredpropertieslist
  for(NSString*requiredPropertyNameinrequiredProperties){
  //getthemappedkeypath
  transformedName=keyMapper.modelToJSONKeyBlock(requiredPropertyName);
  //chekifexistsandifso,addtoincomingkeys
  if([dictvalueForKeyPath:transformedName]){
  [transformedIncomingKeysaddObject:requiredPropertyName];
  }
  }
  //overwritetherawincominglistwiththemappedkeynames
  incomingKeys=transformedIncomingKeys;
  }

  JSONModel(二)
//利用NSSet的isSubsetOfSet:将必传参数表与输入的keyName表对比。如果不是包含关系说明参数传的不够。  //checkformissinginputkeys
  if(![requiredPropertiesisSubsetOfSet:incomingKeys]){
  //getalistofthemissingproperties
  [requiredPropertiesminusSet:incomingKeys];
  //notallrequiredpropertiesarein-invalidinput
  JMLog(@"Incomingdatawasinvalid[%@initWithDictionary:].Keysmissing:%@",self._className_,requiredProperties);
  if(err)*err=[JSONModelErrorerrorInvalidDataWithMissingKeys:requiredProperties];  returnnil;
  }
  //notneededanymore
  incomingKeys=nil;
  requiredProperties=nil;
  //从对象的classProperties列表中循环到dict中取值:(赋值使用KVO操作的setValue:forKey:来做的,这样会直接调用setter函数赋值)
  //loopovertheincomingkeysandsetself'sproperties
  for(JSONModelClassProperty*propertyin[self__properties__]){
  //对于每一个对象的property,通过keyMapper的转换找到对应dictproperty的dictKeyPath,找到值jsonValue。如果没有值,并且这个属性是Optional的就进行下一项property对比。
  //convertkeynameotmodelkeys,ifamapperisprovided
  NSString*jsonKeyPath=property.name;
  if(keyMapper)jsonKeyPath=keyMapper.modelToJSONKeyBlock(property.name);
  //JMLog(@"keyPath:%@",jsonKeyPath);
  //generalcheckfordatatypecompliance
  idjsonValue=[dictvalueForKeyPath:jsonKeyPath];
  //checkforOptionalproperties
  if(jsonValue==nil&&property.isOptional==YES){
  //skipthisproperty,continuewithnextproperty  continue;
  }
  //对找到的值做类型判断,如果不是JSON应该返回的数据类型就报错。(注意:NSNull是可以作为参数回传的)
  ClassjsonValueClass=[jsonValueclass];
  BOOLisValueOfAllowedType=NO;
  for(ClassallowedTypeinallowedJSONTypes){
  if([jsonValueClassisSubclassOfClass:allowedType]){
  isValueOfAllowedType=YES;
  break;
  }
  }
  if(isValueOfAllowedType==NO){
  //typenotallowed
  JMLog(@"Type%@isnotallowedinJSON.",NSStringFromClass(jsonValueClass));
  if(err)*err=[JSONModelErrorerrorInvalidData];
  returnnil;
  }
  //checkifthere'smatchingpropertyinthemodel
  //JSONModelClassProperty*property=classProperties[self.className][key];
  //接着对property的属性与jsonValue进行类型匹配:
  if(property){
  //如果是基本类型(int/float等)直接值拷贝;
  //0)handleprimitives
  if(property.type==nil&&property.structName==nil){
  //justcopythevalue
  [selfsetValue:jsonValueforKey:property.name];
  //skipdirectlytothenextkey
  continue;
  }
  //如果是NSNull直接赋空值;
  //0.5)handlenils
  if(isNull(jsonValue)){
  [selfsetValue:nilforKey:property.name];
  continue;
  }
  //如果是值也是一个JsonModel,递归搞JsonModel
  //1)checkifpropertyisitselfaJSONModel
  if([[property.typeclass]isSubclassOfClass:[JSONModelclass]]){
  //initializetheproperty'smodel,storeit
  NSError*initError=nil;
  idvalue=[[property.typealloc]initWithDictionary:jsonValueerror:&initError];
  if(!value){
  if(initError&&err)*err=[JSONModelErrorerrorInvalidData];
  returnnil;
  }
  [selfsetValue:valueforKey:property.name];
  //forclarity,doesthesamewithoutcontinue
  continue;
  }else{
  //如果property中有protocol解析将jsonValue按照protocol解析,如NSArray<JsonModelSubclass>,protocol就是JsonModelSubclass
  //2)checkifthere'saprotocoltotheproperty
  //)mightornotbethecasethere'sabuiltintransofrmforit
  if(property.protocol){
  //JMLog(@"proto:%@",p.protocol);
  //__transform:forProperty:函数功能:
  //->先判断下protocolClass是否在运行环境中存在,如不存在并且property是NSArray类型,直接报错。否则,直接返回。
  //->如果protocalClass是JsonModel的子类,
  //->如果property.type是NSArray
  //->判断一下是否是使用时转换
  //->如果为使用时转换则输出一个JSONModelArray(NSArray)的子类
  //->如果不是使用时转换则输出一个NSArray,其中的对象全部转换为protocalClass所对应对象
  //->如果property.type是NSDictionary
  //->将value转换为protocalClass所对应对象
  //->根据key存储到一个NSDictionary中输出
  jsonValue=[self__transform:jsonValueforProperty:property];
  if(!jsonValue){
  if(err)*err=[JSONModelErrorerrorInvalidData];
  returnnil;
  }

JSONModel三)
//如果是基本JSON类型(NSString/NSNumber)
  //3.1)handlematchingstandardJSONtypes
  if(property.isStandardJSONType&&[jsonValueisKindOfClass:property.type]){
  //如果是mutable的,做一份MutableCopy
  //mutableproperties
  if(property.isMutable){
  jsonValue=[jsonValuemutableCopy];
  }
  //setthepropertyvalue
  [selfsetValue:jsonValueforKey:property.name];
  continue;
  }
  //如果property.type是NSArray
  //3.3)handlevaluestotransform
  if(
  //如果(类型没有匹配,并且jsonValue不为空)或者是Mutable的property(说明是特殊类型转换)
  (![jsonValueisKindOfClass:property.type]&&!isNull(jsonValue))
  ||
  //thepropertyismutable
  property.isMutable
  ){
  //利用JSONValueTransformer找到源类型
  //searchedaroundthewebhowtodothisbetter
  //butdidnotfindanysolution,maybethat'sthebestidea?(hardly)
  ClasssourceClass=[JSONValueTransformerclassByResolvingClusterClasses:[jsonValueclass]];
  //JMLog(@"totype:[%@]fromtype:[%@]transformer:[%@]",p.type,sourceClass,selectorName);
  //用字符串拼出转换函数的名称字符串,到JSONValueTransformer中去搜索@SEL执行出正确类型
  //buildamethodselectorforthepropertyandjsonobjectclasses
  NSString*selectorName=[NSStringstringWithFormat:@"%@From%@:",
  (property.structName?property.structName:property.type),//targetname
  sourceClass];//sourcename
  SELselector=NSSelectorFromString(selectorName);
  //checkifthere'satransformerwiththatname
  if([valueTransformerrespondsToSelector:selector]){
  //it'sOK,believeme...
  #pragmaclangdiagnosticpush
  #pragmaclangdiagnosticignored"-Warc-performSelector-leaks"
  //transformthevalue
  jsonValue=[valueTransformerperformSelector:selectorwithObject:jsonValue];
  #pragmaclangdiagnosticpop
  [selfsetValue:jsonValueforKey:property.name];
  }else{
  //it'snotaJSONdatatype,andthere'snotransformerforit
  //ifpropertytypeisnotsupported-that'saprogrammermistaked->exception
  @throw[NSExceptionexceptionWithName:@"Typenotallowed"
  reason:[NSStringstringWithFormat:@"%@typenotsupportedfor%@.%@",property.type,[selfclass],property.name]
  userInfo:nil];
  returnnil;
  }
  }else{
  //哪儿都不是的直接存起来
  //3.4)handle"allother"cases(ifany)
  [selfsetValue:jsonValueforKey:property.name];
  }
  }
  }
  }
  //最后调用validate:看看结果是不是有效,没问题就返回了。
  //runanycustommodelvalidation
  NSError*validationError=nil;
  BOOLdoesModelDataValidate=[selfvalidate:&validationError];
  if(doesModelDataValidate==NO){
  if(err)*err=validationError;
  returnnil;
  }
  //modelisvalid!yay!
  returnself;
  }
  程序亮点:
  1、为了提高效率通过static的NSArray和NSDictionary进行解耦。
  2、JSONValueTransformer实现了一个可复用的类型转换模板。
  3、通过runtimefunction解析出property列表,通过property相关函数解析出名称,和Attributes的信息。
  4、NSScanner的使用
  5、NSSet的包含关系判断两个集合的交集
  6、利用[NSObjectsetValue:forKey:]的KVO操作赋值,可以直接调用setter函数,并且可以赋nil到property中
  7、适时给子类一个函数可以修改父类的一些行为
  聪明在于勤奋,天才在于积累,对于学习语言来说,勤奋和积累是非常必要的,把一个技术点悟透,只有反复不断的练习,达内希望每一位同学都能把学习当成一种信仰,不断的充实自己完善自己。
心海(完成2).model3.json 立即下载

相关推荐

iOS json -》模型

NObject+JKCoding 实现JSON转化成模型

JsonModel 遇到类型不统一的数据

这种问题最好还是后天来改。实在不行了 就这样解决咯      解决方法 用id类型去接收data数据,, 用到data时,,按照需要进行类型转换

flg1554112450的博客 1251

model.json

model.json

JSON数据---JSONModel解析

JSONModel 一个解析 JSON 数据的开源库,可以将 JSON 数据直接解析成自定义的 model . 使用 JSONModel 非常简单,只需要将你的 model 类继承自 JSONModel ,而同时 model 中的属性名又恰巧可以和 JSON 数据中的 key 名字一样的话,那么非常恭喜你,你的工作已经完成90%。 JSONModel 不只使用非常方便而且还会帮你检查 JSON

飘风七叶 3496

JSONModel.zip

JSONModel ,JSONModel 是一个 iOS 库可以让你快速创建智能的 JSON 数据模型,可在 iOS 和 ...

八重神子.model3.json

八重神子.model3.json

字符串映射类not support type错误

定义数据类 public class PackageOrderInfo { private String memberId; private String orderId; private Integer packageId; private Date payTime; private Integer businessId; } 接口请求数据: { ...

Wengzhengcun的博客 1万+

json转换model

C# json转换类,方便json和model之间转换。

【iOS】JSONModel源码阅读笔记

JSONModel是一个很经典的源码库,先前基本把iOS的底层看的差不多了,暑假之前都会进行源码与算法学习JSONModel提供了一种方法,得到的JSON数据自动与Model进行匹配还提供了keyMapper将JSON键自动映射到模型的属性还让我们可以自定义错误处理这里再讲一下JSONModel的实现流程:方法中通过获取JSONModel类的属性列表,与传入的JSON数据自动匹配,同时还可以通过KeyMapper修改不相同的映射,如果模型类与JSON。

weixin_72437555的博客 1634

自监督学习与上下文赌博机融合:视觉决策中的协同优化与实战指南

在机器学习领域,自监督学习(Self-Supervised Learning)通过设计前置任务从无标注数据中学习通用表征,已成为解决标注数据稀缺问题的关键技术。其核心原理是利用数据自身的结构生成监督信号,训练编码器提取鲁棒特征。上下文赌博机(Contextual Bandits)作为强化学习的简化分支,专注于在给定上下文信息下做出单步最优决策,平衡探索与利用,广泛应用于推荐系统、广告投放等场景。将两者结合,构建端到端的协同训练框架,能让视觉表征的优化直接服务于最终的决策目标,同时利用自监督任务作为正则化项提

weixin_33721344的博客 520

【AIOPS实战】Dify+Zabbix:构建智能告警分析助手的核心架构与实现

本文详细介绍了如何利用Dify平台与Zabbix-MCP接口构建智能告警分析助手,实现自然语言查询告警、智能分析和报告生成。该系统通过AIOPS技术显著提升运维效率,支持中英文混合查询、自动根因分析,并内置多种优化方案确保稳定可靠。

weixin_29238147的博客 318

iOS——JSONModel

什么是JSONModel 所以JSONModel就是Objective-c的一个开源第三方库,他可以帮我们处理网络请求到的数据,当我们向服务器发送一个请求之后,通过JSONModel把数据转成model就可以很方便我们使用了。 如何使用JSONModel 首先是需要配置环境,当配置好环境后才可以使用JSONModel。 配置环境 首先要在终端中配置CocoaPod,这边可以参考一下之前写的一篇文章,Masonry。 接下来打开终端,cd到需要使用JSONModel的目录,输入touch Podfile文件,

chabuduoxs的博客 908

PaddleOCR GPU部署:从环境配置到避坑实战指南

本文详细介绍了PaddleOCR GPU部署的全过程,从环境配置到避坑实战指南。通过分析常见的部署失败原因,提供硬件兼容性自查、软件环境精配方案以及路径配置的解决方案,帮助用户高效完成GPU加速的OCR任务部署,避免90%的常见错误。

weixin_30839881的博客 418

iOS——JSONModel的使用与JSONModel的嵌套

JSONModel是一个解析JSON数据的开源库,可以将JSON数据直接解析成自定义的model使用 JSONModel 非常简单,只需要将你的 model 类继承自 JSONModel ,而同时 model 中的属性名又恰巧可以和 JSON 数据中的 key 名字一样的话,那么非常恭喜你,你的工作已经完成90%。JSONModel 不只使用非常方便而且还会帮你检查 JSON 数据的完整性,如果 JSON 数据不完整的话是要返回 nil 的。

m0_73348697的博客 1239

电源管理芯片PMIC

(Power Management Integrated Circuits,简称:将电源电压转换为电子设备各部分所需的适当电压水平,包括升压(Boost)、降压(Buck)和升降压(Buck-Boost)转换。:控制和限制流向电子设备各部分的电流,以保护组件免受过电流损害。:管理多个电源轨,为不同的部分提供稳定的电能控制。电源轨指电路板上传输电力的线路。电源监控:提供过电压、欠电压、过电流、过热和短路保护,以防止电子设备损坏。:通过高效的电源转换技术,减少能量损耗,提高能源利用效率。

qq_42786033的博客 1万+

从CTF到实战:Frida Hook无导出SO函数的3种特殊姿势

本文深入探讨了在移动安全逆向工程中,如何利用Frida Hook无导出SO函数的三种高级技巧:字符串引用定位法、调用栈回溯法和内存特征码扫描。针对安卓So层加固和混淆场景,文章结合CTF赛题与实战案例,详细解析了每种方法的原理、实现步骤与适用场景,为安全研究人员提供了从理论到实践的完整解决方案。

jenkins8butler的博客 516

JSONModel的源码解析

JSONModel的源码解析 一、JSONModel和YYModel的比较 1、json中有[NSNull null]类型 — JSONModel和YYModel都有适配 2、异常情况:NSString &amp;amp;amp;lt;-&amp;amp;amp;gt; NSNumber — JSONModel和YYModel都有适配 3、异常情况:NSString &amp;amp;amp;lt;-&amp;amp;amp;gt; NSUInteg

yyq的博客 1022

1553B总线介绍及其硬件方案设计

军用1553B总线 1.简介 简单介绍可参考(https://blog.youkuaiyun.com/ScilogyHunter/article/details/108444231)博主写的很详细。 1553B总线是MIL-STD-1553总线的简称,其中B就是BUS,MIL-STD-1553B总线是飞机内部时分制命令/响应式多路复用数据总线。1553B数据总线标准是20世纪70年代由美国公布的一种串行多路数据总线标准。1553B总线能挂31个远置终端,1553B总线采用指令/响应型通信协议,它有三种终端类型: BC:

小幽余生不加糖 1万+

【iOS】——JSONModel源码

JSONModel框架的作者允许开发者自定义错误阻止模型的转换使用validate方法if (!return NO;*error = [NSError errorWithDomain:@"未成年!return NO;return YES;

m0_73974920的博客 1597

物理AI重构自动驾驶供应链 | 传统Tier1盈利模式崩塌,纯算法/软硬一体双路线落地对比,助力智驾软件商业化与全场景模型迭代

2026年是自动驾驶物理AI规模化落地元年,行业彻底告别传统感知-预测-规划-控制的模块化分层开发范式,迈入以世界模型、物理规则推演、端到端动作生成为核心的全新技术阶段。不同于传统AI仅完成图像识别、目标检测的浅层感知任务,物理AI能够深度理解道路交通中的动力学约束、路面摩擦、车辆博弈、行人运动规律等真实物理逻辑,实现对复杂路况的时序推演与自主决策,从底层重构自动驾驶技术架构。技术迭代同步引发产业链颠覆性变革,沿用数十年的传统自动驾驶Tier1商业模式全面崩塌。

getusushu的博客 289

【DRAM存储器五十七】LPDDR5介绍--read DQ training和WCK DQ training

简述LPDDR5训练中的读写DQ训练

highman110的博客 522

JSONModel的源码

这周看一下看不懂的源码先看JSONModel源码总体而言,JSONModel提供了一种强大且易于使用的方式来处理iOS应用程序中的JSON数据。它提供了类型安全、易于扩展和高度可定制的功能,使得开发人员能够更快速、更轻松地开发高质量的iOS应用程序。

weixin_61196797的博客 784

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【iOS】JSONModel源码学习

笔者学习一下有关于JSONModel的源码的内容,来了解它底层的一个实现过程。

qq_73106050的博客 1196

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

JSONModel的使用

一个解析JSON数据的开源库,可以将JSON数据直接解析成自定义的modelJSONModel是用写的开源库。它包含了接受发送、解析JSON数据,用JSON数据驱动初始化你的类,还能够检验JSON和嵌套模型等功能。

weixin_61558111的博客 1702

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

下一篇: iOS-获取当前时间的年、月、日、时、分、秒
光速之年
博客等级 码龄12年 31粉丝 97原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值