我們接著上回的思路看,上面第一行就是一個條件編譯。
#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庫的整體流程的梳理。