有這麼個模型
@inte***ce author : nsobject
@property nsstring *name;
@property nsstring *birthday;
@end
@inte***ce book : nsobject
@property nsstring *name;
@property nsuinteger pages;
@property author *author;
@end
建立的一般流程是這樣的
book * page = [book new];
page.name = @"天書";
page.pages = 245;
author * writer = [author new];
writer.name = @"孫大聖";
writer.birthday = @"不曉得";
page.author = writer;
使用 yymodel 後,可以這樣
nsstring * path = [nsbundle.mainbundle pathforresource: @"one" oftype: @"json"];
nsstring* jsonstring = [[nsstring alloc] initwithcontentsoffile:path encoding:nsutf8stringencoding error:nil];
nsdata* jsondata = [jsonstring datausingencoding:nsutf8stringencoding];
book * page = [book yy_modelwithjson: jsondata];
yymodel 通過執行時,把我們手動的部分,自動化了
然後實現自動賦值
對其源**,有簡化
yymodel 的方法實現,
是對 nsobject,加擴充套件
@inte***ce nsobject (yymodel)
@end
拿到資料,吐出模型
+ (instancetype)yy_modelwithjson:(id)json
給字典,拿到模型的方法
+ (instancetype)yy_modelwithdictionary:(nsdictionary *)dictionary
其中,這一行
nsobject *one = [cls new];
對應
book * page = [book new];
小結,yymodel 並不神奇,做的事情,也就是建立模型,給模型的屬性填資料
給模型填資料
- (bool)yy_modelsetwithdictionary:(nsdictionary *)dic ;
context.modelmeta = (__bridge void *)(modelmeta);
context.model = (__bridge void *)(self);
context.dictionary = (__bridge void *)(dic);
// 對字典的每乙個鍵值,批量呼叫 modelsetwithdictionaryfunction 方法
// ...
// 省略兩個 if
} else
return yes;
}
進入屬性賦值方法modelsetwithdictionaryfunction
static void modelsetwithdictionaryfunction(const void *_key, const void *_value, void *_context)
進入具體賦值方法modelsetvalueforproperty
對於整型的值,手段類似
呼叫yy_modelsetwithdictionary
,上面的流程,重新來一遍
遞迴的呼叫出現了
// 下面的方法,有大幅簡化,僅用於舉例
static void modelsetvalueforproperty(__unsafe_unretained id model,
__unsafe_unretained id value,
__unsafe_unretained _yymodelpropertymeta *meta)
} break;
default: break;
}} else else if ([value iskindofclass:cls] || !cls) else if ([value iskindofclass:[nsdictionary class]])
} break;
default: break;}}
}
上面的這一句
[cls new];
對應開頭部分
author * writer = [author new];
流程就走完了
**接著看
給乙個 json, 拿到字典,
這個 json ,可以是字串、字典、二進位制資料 nsdata
這邊都做了相應的檢查,和處理
+ (nsdictionary *)_yy_dictionarywithjson:(id)json else if ([json iskindofclass:[nsstring class]]) else if ([json iskindofclass:[nsdata class]])
if (jsondata)
return dic;
}
通過執行時,拿到屬性資訊
入口是,這一句
_yymodelmeta *modelmeta = [_yymodelmeta metawithclass:object_getclass(self)];
進入這個類_yymodelmeta
初始化方法, 看起來嚇人,
又是單例、鎖、訊號量
實際很簡單
有用的**,只有一行
meta = [[_yymodelmeta alloc] initwithclass:cls];
建立兩個單例,快取,和一把鎖,實際是訊號量
然後獲取meta
,
有快取,取快取
沒快取,去建立
通過訊號量這把鎖,保證快取操作,是執行緒安全的
+ (instancetype)metawithclass:(class)cls );
dispatch_semaphore_wait(lock, dispatch_time_forever);
_yymodelmeta *meta = cfdictionarygetvalue(cache, (__bridge const void *)(cls));
dispatch_semaphore_signal(lock);
if (!meta)
}return meta;
}
執行時相關,下篇繼續 YYModel 原始碼分析
instancetype yy modelwithdictionary nsdictionary dictionary 第一步 準備 yymodelmeta 類 分析 1.cache快取 yymodelmeta 類,如果乙個模型已經轉換過,就會儲存到cache裡面,如果下次遇到相同的model,就會...
YYModel原始碼閱讀(一)
專案中一直在使用yymodel來進行model的轉換。自己閱讀了yymodel的原始碼,下面就從最基本的開始對yymodel進行分析。標頭檔案yymodel if has include foundation export double yymodelversionnumber foundation...
YYModel 原始碼解讀(一)之YYModel h
if has include foundation export double yymodelversionnumber foundation export const unsigned char yymodelversionstring import import else import nsob...