30分鐘擼出乙個執行緒安全的YYModel

2021-08-03 19:46:28 字數 4004 閱讀 5504

做ios開發以來,從最開始沒有資料模型,所有資料都靠nsstringnsdictionarynsarrray等系統基礎的物件儲存,到後來自己開始手動擼資料模型,再然後就開始接觸jsonmodel,徹底脫離了枯燥的重複的動作,後來一些國產的一些優秀的資料模型庫也開始嶄露頭角,如mjextension,如yymodel等。但別人的輪子始終是別人的,要是中途爆了胎還得去人家的店裡(github)提出問題,等待修復,可是現實中大多數的時候時間都不允許我們這樣慢慢的等待,所以就有了這篇文章。

在這篇文章中,你可以了解到一些實用的runtime技巧,一些物件導向的思想,最重要的是可以自己做出乙個可以供自己擴充套件的資料模型輪子。輪子雖小但優點在於方便理解,擴充套件性強。

廢話不多說,直接進入正題。

要將資料模型的實現原理,先回想一下我們平時是怎麼用別人的資料模型的。

所以就有了我們的設計思路

下面我們就來實現具體的步驟

name包括n&wrgsvt

這裡面的gs正好對應gettersetter,這兩個比較好理解,都是對應sel的name,不過這個這個時候通過value取出來的是乙個char型字串,這個要注意一下。比如getter就是"group"setter就是"setgroup:"

t就稍稍複雜一點一些,這裡的t就是@\"nsarray"\(如果有兩個protocol則是@\"nsarray),我們可以將它分為三部分@nsarraystudent。其中nsarray是這個屬性的classstudent是對應的protocols,因為protocols可能有多個,所以它是個陣列。同樣的它們也都是char型字串。

最關鍵的是前面的@它代表這個property是個物件,具體這個char所對應的含義可以參考:

其實在objc/runtime.h第1560行至1589行中也有對應的描述。我們將@這樣的字串單獨存入乙個新定義的屬性type

這裡有個tip可以有效的將@\"nsarray分成nsarraystudentstudent2這樣的陣列。

nsstring *type = @"@\"nsarray";

nsmutablearray *values = [type componentsseparatedbycharactersinset:[nscharacterset charactersetwithcharactersinstring:@"@\"<>,"]].mutablecopy;

[values removeobject:@""];

// 最終values = @[@"nsarray",@"student",@"student2"];

到這裡關於一條property最重要的一些資訊我們都得到了:

獲取關鍵的classinfo資訊

區分需要轉化的物件是nsdictionary還是nsarray

nsdictionary中的key與我們剛才記錄在classpropertyinfo中的name進行對比。對比方式嘛就是輪詢。

在這一步我們的目的是得到在我們datamodel中的每個classpropertyinfo對應的在nsdictionaryobject

這句話讀起來可能比較繞口:所以我們舉個��:

還是上文定義的persondatamodel

這個時候傳入的nsdictionary是

那麼這個時候我們要找到的就是persondatamodelname***classpropertyinfo和它對應的value而在這個地方我們就可以做一些比較有意思的事情了,比如白名單黑名單過濾,比如屬性名稱的對映,而這些有意思的方法可以將它都歸為乙個option的協議,並將所有協議單獨歸類出乙個檔案dbmodelprotocol,這樣方便閱讀,也方便維護。

白名單黑名單比較好理解,就是在對應的model裡面接受對應的名單實現是否對這個屬性進行賦值或者不賦值。具體使用類似實現以下兩個協議即可

+ (nsarray *)modelpropertyblacklist

+ (nsarray *)modelpropertywhitelist

屬性名稱的對映其實就我常用的重新命名,比如伺服器返回了我們乙個keyid,但id是乙個隱藏的系統關鍵字,我們乙個會將它重新命名為personid或者teacherid等更容易理解的屬性名稱

我們重新在persondatamodel的基礎上定義乙個teacherdatamodel的資料模型

@inte***ce

teacherdatamodel : persondatamodel

@property (nonatomic, assign) nsuinteger teacherid;

@end

而服務端返回給我們資料模型卻是

這個時候我們就可以在這一步進行一些差異化的對比了:

首先我們先實現協議:

return @;}

當我們輪詢到teacherdatamodelnameteacheridclasspropertyinfo時取出的nsdictionary中對應keyidobject

進行到這已經完成對乙個nsdictionary->datamodel的全過程。

但我相信如果能看到這裡的同學對其他功能應該是已經可以手到擒來了。

做事之前先理清楚思路,功能點全部歸好類才能更好幫助我們完成它!

本文所有**可以在這裡找到:demo

30分鐘玩轉Shell 第乙個Shell指令碼

開啟文字編輯器,新建乙個檔案,擴充套件名為sh sh代表shell 副檔名並不影響指令碼執行,見名知意就好,如果你用php寫shell 指令碼,副檔名就用php好了。輸入一些 bin bash echo hello world 是乙個約定的標記,它告訴系統這個指令碼需要什麼直譯器來執行,即使用哪一種...

今天為了乙個製杖問題調了30分鐘

今天犯了乙個製杖錯誤 include using namespace std intqx,qy,zx,zy queue q int x 13 y 13 bool b 101 101 int tot 101 101 int ans 2 u1,u2 void gs if u2 0 xx zx yy zy...

js 乙個簡單的30分鐘迴圈倒計時

吐槽段 需求的變更是千變萬化的,至少在你說服和你打交道的那位誰誰誰之前。創業公司就是這樣,產品經理乙個想法,就是改改改,管你改起來複雜不複雜,在他們眼裡都是非常簡單的。今天的乙個小改動需求,把活動的倒計時改成乙個迴圈的30分鐘倒計時,沒錯,就是乙個迴圈的30分鐘倒計時,這個活動是永無止境的。技術段 ...