一些有深度的博客我会同步到自己的Github上
这个源码解析系列的文章
前言
iOS开发中,不管是哪种设计模式,Model层都是不可或缺的。而Model层的第三方库常用的库有以下几个
JSON data到对象的转换原理都差不多,一般的顺序如下
- 根据Runtime,动态的获取属性的类型和属性的名字,(如果需要,做一次Json的key的Mapping
- 创建对应的对象实例
- 根据KVC(NSKeyValueCoding协议)来为属性设置值
Mantle就是这样的一个库,个人比较喜欢Mantle,而且在Github的Star也是提到的几个库中最多的。Mantle除了提供JSON和对象的相互转化,继承自MTLModel的对象还自动实现了
NSCopying
NSCoding
isEqual
hash
等几个工具方法。
本文的讲解顺序
首先会讲解几个Runtime的基础知识,不理解这个,也就没办法掌握这几个JSON到Model转化的原理
- 介绍Runtime如何获取某一个类的全部属性的名字
- 介绍Runtime如何动态获取属性的类型
然后,会讲解Mantle本身
- 类的组织架构关系
- JSON到对象的处理流程(对象到JSON的过程类似)
- NSValueTransformer
- 如何自动实现NSCoding,NSCopying,hash等方法
- 异常处理
- 其他认为有用的,例如编译选项等
本文会很长,希望读者看完后能有些许收获,如果发现有任何地方有问题,欢迎指正,我会及时修改。
利用Runtime动态获取类的属性
首先,写两个类
@interface Base : NSObject
@property (copy,nonatomic)NSString * baseProperty;
@end
@interface Demo : Base
@property (nonatomic,strong)NSDate * createAt;
@property (nonatomic,copy)NSString * name;
@property (nonatomic,assign)CGFloat count;
@end
然后, 写一个方法来Log Property
-(void)logAllPropertys{
uint count;
objc_property_t * propertys = class_copyPropertyList(Demo.class,&count);
@try {
for (int i = 0; i < count ; i++) {
objc_property_t property = propertys[i];
NSLog(@"%@",@(property_getName(property)));
}
}@finally {
free(propertys);
}
}
执行这个方法的Log
2016-05-26 22:51:48.996 LearnMantle[4670:165290] createAt
2016-05-26 22:51:49.001 LearnMantle[4670:165290] name
2016-05-26 22:51:49.001 LearnMantle[4670:165290] count
不难发现class_copyPropertyList
仅仅是获取了当前类的属性列表,并没有获取基类的属性对象。所以对上述方法进行修改
-(void)logAllPropertys{
Class cls = Demo.class;
while (![cls isEqual:NSObject.class]) {
uint count;
objc_property_t * propertys;
@try {
propertys = class_copyPropertyList(cls,&count);
cls = cls.superclass;
for (int i = 0; i < count ; i++) {
objc_property_t property = propertys[i];
NSLog(@"%@",@(property_getName(property)));
}
}@finally {
free(propertys);
}
}
}
这里又个Tips: