1.映射綁定做了緩存
YYModel有兩個(gè)映射方法:modelCustomPropertyMapper和modelContainerPropertyGenericClass,當(dāng)時(shí)使用的時(shí)候發(fā)現(xiàn)這兩個(gè)方法只調(diào)用一次,一開始以為是使用load方法調(diào)用的,看了代碼才發(fā)現(xiàn)不是的。

從上圖的線程調(diào)用可以看出來(lái),modelContainerPropertyGenericClass是在第一次調(diào)用yy_modelSetWithJSON的時(shí)候調(diào)用的,我們把代碼定位到下面的代碼
+ (instancetype)metaWithClass:(Class)cls {
if (!cls) return nil;
static CFMutableDictionaryRef cache;
static dispatch_once_t onceToken;
static dispatch_semaphore_t lock;
dispatch_once(&onceToken, ^{
cache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
lock = dispatch_semaphore_create(1);
});
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
_YYModelMeta *meta = CFDictionaryGetValue(cache, (__bridge const void *)(cls));
dispatch_semaphore_signal(lock);
if (!meta || meta->_classInfo.needUpdate) {
meta = [[_YYModelMeta alloc] initWithClass:cls];
if (meta) {
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
CFDictionarySetValue(cache, (__bridge const void *)(cls), (__bridge const void *)(meta));
dispatch_semaphore_signal(lock);
}
}
return meta;
}
分析:
meta = [[_YYModelMeta alloc] initWithClass:cls];會(huì)調(diào)用映射綁定,而不是我之前猜測(cè)的在load或initialize方法里面調(diào)用的。
使用CFDictionary創(chuàng)建了cache緩存,dispatch_once(&onceToken, ^{})確保了初始化過(guò)程只有一次。
線程安全方面使用的是dispatch_semaphore ,之前我做過(guò)實(shí)驗(yàn),dispatch_semaphore 的性能還是很高的,速度在我的測(cè)試中排列第三,比他高的還有一個(gè)遞歸鎖,還有一個(gè)dispatch_barrier_async/dispatch_barrier_sync,然而遞歸鎖在這里不太合適,dispatch_barrier的話需要進(jìn)行線程切換,所以被作者放棄了。
meta的創(chuàng)建沒(méi)有在線程鎖里面,雖然這樣meta可能會(huì)被創(chuàng)建多次,這里這樣做主要是保證了鎖的區(qū)域足夠小。
2.json到model,model到NSDictionary或者NSArray的轉(zhuǎn)換
根據(jù)映射可以直接轉(zhuǎn)換到model對(duì)象:
+ (nullable instancetype)yy_modelWithJSON:(id)json;
+ (nullable instancetype)yy_modelWithDictionary:(NSDictionary *)dictionary;
- (BOOL)yy_modelSetWithJSON:(id)json;
- (BOOL)yy_modelSetWithDictionary:(NSDictionary *)dic;
根據(jù)映射可以轉(zhuǎn)成NSDictionary或者NSArray或者NSData或者NSString:
- (nullable id)yy_modelToJSONObject;
- (nullable NSData *)yy_modelToJSONData;
- (nullable NSString *)yy_modelToJSONString;
這里需要注意
yy_modelToJSONObject方法并不是model一定會(huì)轉(zhuǎn)成[String:String]或者[String]類型的,而是[String:AnyObject]或者[AnyObject],也就是說(shuō),model轉(zhuǎn)出來(lái)的可能字典嵌套數(shù)組的類型,如果說(shuō)需要把數(shù)組轉(zhuǎn)成json字符串傳給服務(wù)器,那么還是需要進(jìn)行二次轉(zhuǎn)換的。
3.yy_modelCopy
yy_modelCopy現(xiàn)在有BUG,model是生成一個(gè)新的對(duì)象了,但是model里面的屬性并沒(méi)有,體現(xiàn)在 NSMutablexxxx和其他自定義類上,由于內(nèi)存地址還是一個(gè),對(duì)這些屬性的修改會(huì)造成原model的修改
4.runtime
YYModel大量的使用了runtime,屬性的獲取,賦值等操作都使用了runtime,這部分篇幅限制就不多做介紹了
開源庫(kù)的存在大大方便了我們的開發(fā),我們?cè)谑褂玫耐瑫r(shí)應(yīng)該多去閱讀源碼,每個(gè)人寫代碼的習(xí)慣都不一樣,不對(duì)比怎么能知道自己習(xí)慣的好壞呢,而且最重要的是可以學(xué)習(xí)到優(yōu)秀的代碼邏輯,什么時(shí)候用什么,該怎么用,為什么這樣用。大神不是一開始就是大神,都是一步一步走出來(lái),不學(xué)習(xí)怎么能成長(zhǎng)。