JFModel

真的好久好久沒寫點(diǎn)東西了,先對這段時(shí)間的總結(jié)吧。

首先對技術(shù)的熱忱從未消減,但是總是什么都想學(xué),什么都是半途而廢,比如python,H5都是自學(xué)一段時(shí)間后 就沒有繼續(xù)下去,這是病得治。
再說說鍛煉吧,最近有一個(gè)很有成就感的就是 學(xué)會的蛙泳,從剛開始的各種喝水到現(xiàn)在游輕松游200米不是問題,最近又開始解鎖自由泳。。。
發(fā)現(xiàn)一個(gè)很有有趣的東西,學(xué)游泳和學(xué)技術(shù)有很多相似的地方,比如說:剛開始的時(shí)候,覺得很興奮,啥都要都要嘗試下,然后就不在意 腿部動(dòng)作,不在意腿部動(dòng)作,不在意手的動(dòng)作,不在意呼吸節(jié)奏,然后就各種喝水嗆水,等自己會游一點(diǎn)了就很有成就感,就想游的標(biāo)準(zhǔn),游的更遠(yuǎn)。學(xué)技術(shù),學(xué)新的語言也是一樣的。剛開始很興奮,然后就渾淪吞棗,結(jié)果處處碰壁,到沮喪,到學(xué)到一點(diǎn)東西就有點(diǎn)成就感的過程真的和游泳很像。

好了回歸正題。
看到這個(gè)標(biāo)題差不多就有點(diǎn)感覺 這次和大家分享的東西。沒錯(cuò)就是一個(gè)常用并且現(xiàn)在網(wǎng)上很多類似的框架,如:MJExtension , YYModel,Mantle等等 字典轉(zhuǎn)模型框架。
接下來,我會說下我的JFModel的實(shí)現(xiàn)過程,和用法。

實(shí)現(xiàn)過程:

首先我們看下數(shù)據(jù)結(jié)構(gòu) User.h 這是一個(gè)

用戶模型

typedef enum {
    SexMale,
    SexFemale
} Sex;

@interface User : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *icon;
@property(nonatomic,copy)NSString *age;
@property(nonatomic,copy)NSString *height;
@property(nonatomic,copy)NSString *money;
@property(nonatomic,copy)NSString *sex;
@property(nonatomic,copy)NSString *gay;

@end

字典

NSDictionary *dict = @{
                           @"name" : @"linjianfang",
                           @"icon" : @"jf.png",
                           @"age" : @"20",
                           @"height" : @1.75,
                           @"money" : @"1000009.9999",
                           @"sex" : @(SexFemale),
                           @"gay" : @"true",
                           };

我們想要的結(jié)果如下:

    NSLog(@"name=%@, icon=%@, age=%zd, height=%@, money=%@, sex=%d, gay=%d", user.name, user.icon, user.age, user.height, user.money, user.sex, user.gay);

好,我們先明確是目的,用模型里面的屬性名做key去字典里面找出對應(yīng)的value,用模型的屬性的類型將值轉(zhuǎn)為正確的類型。
因?yàn)槟P痛蠖嗲闆r下都是純凈的都是繼承NSobject的 所以我們就建一個(gè)NSobject的分類

/** 
 * Describes the properties declared by a class.
 * 
 * @param cls The class you want to inspect.
 * @param outCount On return, contains the length of the returned array. 
 *  If \e outCount is \c NULL, the length is not returned.        
 * 
 * @return An array of pointers of type \c objc_property_t describing the properties 
 *  declared by the class. Any properties declared by superclasses are not included. 
 *  The array contains \c *outCount pointers followed by a \c NULL terminator. You must free the array with \c free().
 * 
 *  If \e cls declares no properties, or \e cls is \c Nil, returns \c NULL and \c *outCount is \c 0.
 */
OBJC_EXPORT objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);

Putting these together, you can print a list of all the properties associated with a class using the following code:

image.png

我們打印出來這個(gè)user屬性的名字就是我們定義的屬性的名字,屬性的類型是T開始和后面的一些東西,等會下面會解釋這個(gè)個(gè)什么東東

name:name---attributes:T@"NSString",C,N,V_name
name:icon---attributes:T@"NSString",C,N,V_icon
name:age---attributes:TI,N,V_age
name:height---attributes:T@"NSString",C,N,V_height
name:money---attributes:T@"NSNumber",&,N,V_money
name:sex---attributes:Ti,N,V_sex
name:gay---attributes:Tc,N,GisGay,V_gay

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html

Property Type String

You can use the property_getAttributes function to discover the name, the @encode type string of a property, and other attributes of the property.

The string starts with a T followed by the @encode type and a comma, and finishes with a V followed by the name of the backing instance variable. Between these, the attributes are specified by the following descriptors, separated by commas:

image.png

我們?nèi)〕雒總€(gè)type 所對應(yīng)的 code 拿到這些code我們就可以知道這是什么類型

- (void)getTypeCode:(NSString *)code
{
    if ([code isEqualToString:JFPropertyTypeId]) {
        _idType = YES;
    } else if (code.length > 3 && [code hasPrefix:@"@\""]) {
        // 去掉@"和",截取中間的類型名稱
        _code = [code substringWithRange:NSMakeRange(2, code.length - 3)];
        _typeClass = NSClassFromString(_code);
        _numberType = (_typeClass == [NSNumber class] || [_typeClass isSubclassOfClass:[NSNumber class]]);
        // 判斷是否是模型類
        _fromFoundation = [NSObject isClassFromFoundation:_typeClass];
    }
    
    // 是否為數(shù)字類型
    NSString *lowerCode = code.lowercaseString;
    NSArray *numberTypes = @[JFPropertyTypeInt, JFPropertyTypeShort, JFPropertyTypeBOOL1, JFPropertyTypeBOOL2, JFPropertyTypeFloat, JFPropertyTypeDouble, JFPropertyTypeLong, JFPropertyTypeChar];
    if ([numberTypes containsObject:lowerCode]) {
        _numberType = YES;
        
        if ([lowerCode isEqualToString:JFPropertyTypeBOOL1]
            || [lowerCode isEqualToString:JFPropertyTypeBOOL2]) {
            _boolType = YES;
        }
    }
}

定義一個(gè)常量類來描述這些code

/**
 *  成員變量類型(屬性類型)
 */
NSString *const JFPropertyTypeInt = @"i";
NSString *const JFPropertyTypeShort = @"s";
NSString *const JFPropertyTypeFloat = @"f";
NSString *const JFPropertyTypeDouble = @"d";
NSString *const JFPropertyTypeLong = @"q";
NSString *const JFPropertyTypeChar = @"c";
NSString *const JFPropertyTypeBOOL1 = @"c";
NSString *const JFPropertyTypeBOOL2 = @"b";
NSString *const JFPropertyTypePointer = @"*";

NSString *const JFPropertyTypeIvar = @"^{objc_ivar=}";
NSString *const JFPropertyTypeMethod = @"^{objc_method=}";
NSString *const JFPropertyTypeBlock = @"@?";
NSString *const JFPropertyTypeClass = @"#";
NSString *const JFPropertyTypeSEL = @":";
NSString *const JFPropertyTypeId = @"@";

extern NSString *const JFPropertyTypeInt;
extern NSString *const JFPropertyTypeShort;
extern NSString *const JFPropertyTypeFloat;
extern NSString *const JFPropertyTypeDouble;
extern NSString *const JFPropertyTypeLong;
extern NSString *const JFPropertyTypeLongLong;
extern NSString *const JFPropertyTypeChar;
extern NSString *const JFPropertyTypeBOOL1;
extern NSString *const JFPropertyTypeBOOL2;
extern NSString *const JFPropertyTypePointer;

extern NSString *const JFPropertyTypeIvar;
extern NSString *const JFPropertyTypeMethod;
extern NSString *const JFPropertyTypeBlock;
extern NSString *const JFPropertyTypeClass;
extern NSString *const JFPropertyTypeSEL;
extern NSString *const JFPropertyTypeId;

image.png

現(xiàn)在我們再統(tǒng)一下 目的:

1.拿到模型的屬性名,和對應(yīng)的數(shù)據(jù)類型. (OK)

2.用該屬性名作為鍵去字典中尋找對應(yīng)的值.(OK)

3.拿到值后將值轉(zhuǎn)換為屬性對應(yīng)的數(shù)據(jù)類型.(OK)

4.賦值.

接下來再整理下 目錄結(jié)構(gòu)

image.png

如上:整個(gè)JFModel的框架已經(jīng)搭好了

怎么使用:
https://github.com/tubie/JFModel

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

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,540評論 19 139
  • 1. 世界足夠大 但我愿意再小一些—— 在寂靜里舞蹈 這是你從未有過的自在和歡愉 2. 你的疼痛,你的傷口 對不起...
    憂傷沒有傷口閱讀 142評論 3 4
  • 韓國國家公園管理公團(tuán) 2005年,韓國留學(xué)生韓相一在《中國園林》發(fā)表文章,詳細(xì)地介紹了韓國國家公園形成的歷史和演變...
    wwwWo閱讀 1,339評論 0 2
  • 今天下班到圖書館轉(zhuǎn)悠了一圈,走到基金、期貨書籍的位置不自覺地停下來翻了一陣子,五花八門的投資書籍,其實(shí)對于我這個(gè)對...
    A00小淺閱讀 347評論 0 2
  • 本文目錄: 簡介 快速通道 翻譯--image庫 1. 簡介 Rust這門編程語言魅力非常。奈何在國內(nèi)風(fēng)名不顯,對...
    被叫做逸軒的可兒閱讀 4,235評論 0 4

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