利用Runtime写一个JSON转Model的工具

前言


好久没有写过新文章了,最近一直在忙工作的事情,我的新浪微博开源项目也停止了一周时间,目前完成了60%,就先写一篇关于JSON转Model的文章和大家聊聊天吧,为什么会写一个这个小工具呢,请看文末😄


核心方法Runtime的介绍


1. Runtime是什么?

顾名思义:Runtime就是运行时的意思,是系统在运行时的一些机制,其中最主要的就是消息机制,举个常用的例子,在面向对象编程的语言中,万物皆对象,对象如何调用方法呢,
[target excuteSEL],需要一个对象,需要一个方法名,系统在运行时会自动转换成以下的形式:
objc_msgSend(target,@selector(excuteSEL:))

关于Runtime的详细介绍,网上有很多,这里就不做过多描述了。


2.Runtime的常见用法

注:使用时需要#import

* 1 方法替换(黑魔法)

举个例子来说明一下:
将调用A方法替换为调用B方法

* 2 获取对象的属性和方法

注:获取对象的属性,这个方法在JSON转Model可以说是核心方法了
举例说明:


* 2 设置对象关联

定义:关联是指把两个对象相互关联起来,使其中的一个对象作为另外一个对象的一部分
再举个例子,我在对象中定义了一个属性

Tips:设置对象关联需要以下几个要点:
源对象关键字关联的对象 关联策略
解释一下:这里我将@"content_yeah"这个对象与self使用OBJC_ASSOCIATION_RETAIN_NONATOMIC策略关联到一起,意思就是在self的生命周期之内关联的对象都不会被释放,通过这个方法,可以实现动态向类里面添加属性
另外还有一些关联的方法,如

  • 断开关联: 设置关联对象为nil即可
    objc_setAssociatedObject(self, &associatedKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  • 断开这个对象的所有关联关系


JSON转Model工具的主要介绍


1. 为什么会写这样一个工具

很多时候我们并不是缺少实力,而且是缺少一种彼可取而代之的勇气,为什么会有MJExtensionYYModel的产生,查看源代码的过程中我有种想死的感觉,但是知道实现的原理后,为什么不能自己去实现一个呢?这个工具的源代码非常简单,我写这个工具的目的只是为了告诉朋友们,真的不复杂,不要因为看着复杂就放弃了自己动手的冲动

2. 工具的整体步骤简介

着重介绍一下我的思考过程

  • 1 核心方法?
    利用Runtime可以遍历出对象的所有属性,然后利用递归的思想逐层解析JSON
  • 2 怎么去做?
    基本所有的Model继承NSObject,我们可以写一个NSObjectCategory,然后在其中写一些解析方法,我们需要一个对照JSON字符串的解析路径字典,比如说JSON的属性名称为dog,我们的对象属性名称想定义为xiaogou,这就需要手写一个字典将解析中遇到的dog都给映射为xiaogou
  • 3 开始动手吧

3. 主要代码介绍:


* 1 NSObject+CMModel 介绍

下面着重解释一下.m文件中的内容

取得对象的所有属性及其对应的类型
Tips: 这里自己写了一个类,将对象的属性及其名称封装到一个类型为CMProperty的数组

  • 1 CMProperty类简介

  • 2 获取对象属性及其类型,并且将其封装为类型为CMProperty的数组

开始解析

* 2 CMObject 介绍

这个类为实际进行解析工具的类,或者可以称之为工具,这里我们需要特殊对待NSArrayNSDictionaryint、float等基本类型

Tips: 下面代码可能看着会不舒服,我说一下整体的思路

* 1 NSObject+CMModel中将封装的属性数组传递过来,我们一个接一个的对属性进行遍历构造

2 遍历详解:举例,碰到NSArray的属性时,我们去看要解析的类中实现的- (NSDictionary )dict_CMModelWIthArrayClass这个方法,找到目的对象的类型OBJClass,然后将JSON字典拆分后利用- (instancetype)cm_initWithJSONString:(NSString *)jsonString这个方法创建一个OBJClass类型的对象,并且添加到数组中,创建完后,使用KVC将数组赋给源对象,具体代码看下面


4. 如何使用


举例说明:
这里有三个类
Animals(动物)

—实现方法:

Dog(狗)

—实现方法

Pig(猪)

—实现方法

调用方法

写在后面的话

这个项目并不完善,比如说对于其中日期的格式化,非空的一些判断等,其中也有一些bug,本文权当是抛砖引玉,利用Runtime可以做很多事情,比如你可以实现,一句话完成归档与解归档,不会再出现Model属性过多时重写initWithCoderencodeWithCoder的尴尬了,so,有时候我们更缺的是一种思考问题的方式,共勉!

PS:欢迎来我的简书、Github、个人博客交流😄

文中的Demo下载地址

1 2 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部