移动互联时代,JSON作为一种数据传输格式几乎随处可见。作为iOS开发者,收到一串JSON字符串要怎么处理?我想多数情况下是需要将它转成自定义的NSObject对象再使用,对于这个转换的过程,大部分人是这么做的:
|
|
这样的代码没错,但也绝对说不上优雅,model里面的属性越多,冗余的代码量也相应越多。对于这个问题,自然是有更好的解决方案,比如说这样:
|
|
两行代码足矣,当然,实现这个功能,实际上是把很多背后的工作交给JSONModel这个开源包去做了。至于其实现原理,则主要是基于Objective-C Runtime的反射机制。
关于反射
《Thinking in Java》中将反射称解释为运行时的类信息,说白了就是这个类信息在编译的时候是未知的,需要在程序运行期间动态获取,而这正是我们之前试图去解决的问题。对于从网络上获取到的一段JSON字符串,在代码编译期间当然是无法知晓的。虽然这里说的是Java语言,但是对于Objective-C,这种反射机制也是同样支持的。
JSONModel中的实现
打断点记录了下JSONModel这个类中的方法调用顺序如下:
调用顺序
对象属性的获取则主要在最后一个inspectProperties方法
|
|
在这边可以看到基本步骤如下
- 通过调用自身的class方法获取当前类的元数据信息
- 通过runtime的 class_copyPropertyList 方法取得当前类的属性列表,以指针数组的形式返回
- 遍历指针数组,通过property_getName获取属性名,property_getAttributes获取属性类型
- 使用NSScanner来扫描属性类型字符串,将类似如下的形式"T@"NSNumber",&,N,V_id",处理成NSNumber,逐个属性循环处理
- 将所有处理好的数据放入propertyIndex这个字典中
- 通过objc_setAssociatedObject将这些数据关联到kClassPropertiesKey
|
|
以上就是JSONModel中使用反射机制实现的类属性获取过程,相比常见的逐个取值赋值的方式,这种方法在代码上的确简洁优雅了很多,特别是对于使用的类属性比较复杂的情况,免除了很多不必要的代码。