SCJSONUtil

Version License Platform

特性

  1. 小巧方便,功能强大
  2. 支持映射属性名(比如服务器返回的是id,我们的model里可定义为uid)
  3. 类型自动匹配(比如服务器返回的是Number,model里定义的是String,那么就会解析为 String)

使用 CocoaPods 安装

Podfile 文件里添加:

target 'TargetName' do
    pod 'SCJSONUtil'
end

使用说明

《一看二建三解析》,直接看代码比较直观:

{
    "code": "0",
    "content": {
        "gallery": [
                    {
                    "isFlagship": "0",
                    "name": "白色情人节 与浪漫牵手",
                    "pic": "http://pic16.shangpin.com/e/s/15/03/06/20150306174649601525-10-10.jpg",
                    "refContent": "http://m.shangpin.com/meet/189",
                    "type": "5"
                    },
                    ...
                    ]
      }
}
@interface GalleryModel : NSObject

@property (nonatomic, copy) NSString *isFlagship;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *pic;
@property (nonatomic, copy) NSString *refContent;
@property (nonatomic, copy) NSString *type;

@end
假设responseJSON是服务器返回的json数据,常规的写法是先判断 code 是否等于 0,然后再取出 gallery 对应的json 转成 model; 然而 SCJSONUtil 
提供了更加便捷的方法完成这些步骤:

//1.根据 keypath 取出目标json
id findedJSON = SCFindJSONwithKeyPath(@"content/gallery", responseJSON); 
//2.使用 JSONUtil 解析
NSArray *models = SCJSON2Model(findedJSON, @"GalleryModel");
//models 就是你想要的GalleryModel数组了!

其他的用法,可以参考demo。


核心思想

  1. 递归:JSON 是可以嵌套的,因此这是一个递归的问题;
  2. 遍历 JSON,根据遍历出的 json 里的key,去 model 里查找对应的映射名或者属性名
  3. 适当的地方进行 ValueTransfer,做到类型自动匹配
  4. 通过 kvc 给 model 赋值

其他 JSON 转 Model 框架的大致流程

这里要解释下第二点,因为这里我和其他的 JSON 转 Model 框架的实现大不相同!先来看下其他的主流思想:

JSONUtil 转 Model 流程

JSONUtil 不做 cache 的原因

知道了主流做法后,再来看下 JSONUtil 是如何处理的吧,你会发现 JSONUtil 有很有特色,因为随大流地的去模仿做 cache ,遍历 model 的全部属性,之所以没有这么做,是因为我觉得 没有必要

这是我的做的测试:

    NSDictionary *userInfoDic = [self readUserInfo];

    [self testCount:100000 work:^{
        UserInfoModel *uModel = [UserInfoModel instanceFormDic:userInfoDic];
    }];
    // 10000 次转换耗时:0.51412s
    // 100000 次转换耗时:4.61152s

也就是说使用 JSONUtil 转换一个嵌套4层(里面也有数组)的 model ,转换一次需要: 0.0514ms.

为什么 JSONUtil 选择遍历服务器返回的 JSON ?

遍历终究是要做的,有两种做法,一种是遍历 model的所有属性,另一种是遍历 服务器返回的json;究竟如何选择,困扰了我许久,最后我选择了后者,因为前者的代价较高,需要层层向上遍历,最可恶的是递归的出口不好把握,因此选择了后者规避了这个问题!

另一方面选择后者是因为,根据我解析的习惯是,服务器定义的字段我都会解析,但是有的字段服务器可能不返回,如果按照前者的遍历方式,会增加几次多余的遍历;当然我否定使用后者不会出现多余的遍历,这个定义model的习惯和服务器返回json的空值都有关系!

版本