1.對映繫結做了快取
YYModel有兩個對映方法:modelCustomPropertyMapper和modelContainerPropertyGenericClass,當時使用的時候發現這兩個方法只呼叫一次,一開始以為是使用load方法呼叫的,看了程式碼才發現不是的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
+ (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];會呼叫對映繫結,而不是我之前猜測的在load或initialize方法裡面呼叫的。
使用CFDictionary建立了cache快取,dispatch_once(&onceToken, ^{})
確保了初始化過程只有一次。
執行緒安全方面使用的是dispatch_semaphore ,之前我做過實驗,dispatch_semaphore 的效能還是很高的,速度在我的測試中排列第三,比他高的還有一個遞迴鎖,還有一個dispatch_barrier_async/dispatch_barrier_sync,然而遞迴鎖在這裡不太合適,dispatch_barrier的話需要進行執行緒切換,所以被作者放棄了。
meta的建立沒有線上程鎖裡面,雖然這樣meta可能會被建立多次,這裡這樣做主要是保證了鎖的區域足夠小。
2.json到model,model到NSDictionary或者NSArray的轉換
根據對映可以直接轉換到model物件:
1 2 3 4 |
+ (nullable instancetype)yy_modelWithJSON:(id)json; + (nullable instancetype)yy_modelWithDictionary:(NSDictionary *)dictionary; - (BOOL)yy_modelSetWithJSON:(id)json; - (BOOL)yy_modelSetWithDictionary:(NSDictionary *)dic; |
根據對映可以轉成NSDictionary或者NSArray或者NSData或者NSString:
1 2 3 |
- (nullable id)yy_modelToJSONObject; - (nullable NSData *)yy_modelToJSONData; - (nullable NSString *)yy_modelToJSONString; |
這裡需要注意
yy_modelToJSONObject方法並不是model一定會轉成[String:String]或者[String]型別的,而是[String:AnyObject]或者[AnyObject],也就是說,model轉出來的可能字典巢狀陣列的型別,如果說需要把陣列轉成json字串傳給伺服器,那麼還是需要進行二次轉換的。
3.yy_modelCopy
yy_modelCopy現在有BUG,model是生成一個新的物件了,但是model裡面的屬性並沒有,體現在 NSMutablexxxx和其他自定義類上,由於記憶體地址還是一個,對這些屬性的修改會造成原model的修改
4.runtime
YYModel大量的使用了runtime,屬性的獲取,賦值等操作都使用了runtime,這部分篇幅限制就不多做介紹了
開源庫的存在大大方便了我們的開發,我們在使用的同時應該多去閱讀原始碼,每個人寫程式碼的習慣都不一樣,不對比怎麼能知道自己習慣的好壞呢,而且最重要的是可以學習到優秀的程式碼邏輯,什麼時候用什麼,該怎麼用,為什麼這樣用。大神不是一開始就是大神,都是一步一步走出來,不學習怎麼能成長。
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!
任選一種支付方式