YYModel代碼分析筆記

1.映射綁定做了緩存

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

yymodel方法流程圖.png

從上圖的線程調(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)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容