我们接着上回的思路看,上面第一行就是一个条件编译。
#if !__has_feature(objc_arc)
#error The JSONMOdel framework is ARC only, you can enable ARC on per file basis.
#endif
意思就是 JSONModel 只支持 arc 并不支持 marc 。
之后是3段全局变量的声明
#pragma mark - associated objects names
static const char * kMapperObjectKey;
static const char * kClassPropertiesKey;
static const char * kClassRequiredPropertyNamesKey;
static const char * kIndexPropertyNameKey;
#pragma mark - class static variables
static NSArray* allowedJSONTypes = nil;
static NSArray* allowedPrimitiveTypes = nil;
static JSONValueTransformer* valueTransformer = nil;
static Class JSONModelClass = NULL;
#pragma mark - model cache
static JSONKeyMapper* globalKeyMapper = nil;
分别是关联引用的 Key ,类的静态全局变量,还有一个 globalKeyMapper 。为什么要使用关联引用?因为关联引用可以在不关注具体实现的情况下存储键值,而且多个子类之间互不影响,也不会暴露属性给子类具有良好的封装。用在需要被继承的 JSONModel 上好处不言而喻。
kMapperObjectKey 为了保存子类自己 Mapper
kClassPropertiesKey 为了保存类中的属性在 runtime 中的解析结果
kClassRequiredPropertyNamesKey 储存必须解析的属性名
kIndexPropertyNameKey 储存符合 Index 协议的属性名
接下来使用的全局静态变量是因为这些值都是在 JSONModel 类中初始化不需要改变的值,子类不能修改,需要使用。命名非常直观大家可以非常简单的通过代码读出。
进入代码部分整个代码因为上一篇讲过了,整个的初始化入口均为 Dictionary 其他的初始化也都是调用该方法。而第一个执行的肯定是 load 方法,为 JSONModel 做了必要的初始化工作。
-(id)initWithDictionary:(NSDictionary*)dict error:(NSError**)err
该方法首先先调用了init方法中的 __setup__ 方法,在runtime环境中对 class 对象的属性进行解析,举个例子 T@\"NSString\",R,GisIntReadOnlyGetter,V_intReadOnlyGetter 这就是属性的描述,大概说下,T是一个开头字段 @ 表示为一个 OC 对象, NSString 为属性类型,为复合的协议,R 为只读,G 为 GcustomGetter 后面跟着名字,V 是属性的名字。
在 initWithDictionary 中有两个主要的方法
-(BOOL)__doesDictionary:(NSDictionary*)dict matchModelWithKeyMapper:(JSONKeyMapper*)keyMapper error:(NSError**)err
主要用来处理 mapper 的操作和对数据完整性的解析。
-(BOOL)__importDictionary:(NSDictionary*)dict withKeyMapper:(JSONKeyMapper*)keyMapper validation:(BOOL)validation error:(NSError**)err
主要用来对 JSON 数据解析并赋值。
以上是JSONModel库的整体流程的梳理。