YYModel 2019-06-24

前言
同項目中同事使用YYModel割以,比原生的要簡單高效許多!1炯ァ珊泳!
YYModel是YYKit的高效組件之一,在實際場景中的非常實用拷沸,運用于項目中使用MVC或MVVM架構時色查,使用model做數(shù)據(jù)處理。

自動轉換模型數(shù)據(jù)
自動檢測數(shù)據(jù)安全性撞芍,避免carch
無需繼承其他類秧了,使用方便
適用model各種數(shù)據(jù)加載運用場景

在使用之前先展示一些YYModel比較常用的方法,后面會具體介紹用法
// 字典轉模型

  • (nullable instancetype)modelWithDictionary:(NSDictionary *)dictionary;
    // json轉模型
  • (nullable instancetype)modelWithJSON:(id)json;
    // 模型轉NSObject
  • (nullable id)modelToJSONObject;
    // 模型轉NSData
  • (nullable NSData *)modelToJSONData;
    // 模型轉json字符串
  • (nullable NSString *)modelToJSONString;
    // 模型深拷貝
  • (nullable id)modelCopy;
    // 判斷模型是否相等
  • (BOOL)modelIsEqual:(id)model;
    // 屬性數(shù)據(jù)映射序无,用來定義多樣化數(shù)據(jù)時轉換聲明
  • (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper;
    // 屬性自定義類映射验毡,用來實現(xiàn)自定義類的轉換聲明
  • (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass;
    // 屬性黑名單,該名單屬性不轉換為model
  • (nullable NSArray<NSString *> *)modelPropertyBlacklist;
    // 屬性白名單帝嗡,只有該名單的屬性轉換為model
  • (nullable NSArray<NSString *> *)modelPropertyWhitelist;
    // JSON 轉為 Model 完成后晶通,該方法會被調用,返回false該model會被忽略
    // 同時可以在該model中做一些哟玷,轉換不能實現(xiàn)的操作狮辽,如NSDate類型轉換
  • (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;
    // Model 轉為 JSON 完成后,該方法會被調用巢寡,返回false該model會被忽略
    // 同時可以在該model中做一些喉脖,轉換不能實現(xiàn)的操作,如NSDate類型轉換
  • (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic

運用場景
1抑月、簡單的數(shù)據(jù)交換
YYModel最簡單的使用树叽,在正常的數(shù)據(jù)調用,創(chuàng)建一個model類YYPersonModel谦絮,增加幾個屬性菱皆。
// YYPersonModel.h
@interface YYPersonModel : NSObject

@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) int age;
@property (copy, nonatomic) NSString *sex;

@end

接著在viewController導入<NSObject+YYModel.h>頭文件,直接進行賦值就可以了挨稿,數(shù)據(jù)類型可可以是JSON/Dictionary仇轻,具體的可以看<NSObject+YYModel.h>給出的方法。
// ViewController.m
NSDictionary *dic = @{
@"name":@"張三",
@"age":@(12),
@"sex":@"男"
};
// 將數(shù)據(jù)轉模型
YYPersonModel *model = [YYPersonModel modelWithDictionary:dic];
// 將模型轉數(shù)據(jù)
NSDictionary *dics = [model modelToJSONObject];

使用起來是不是變得特別方便奶甘,會自動根據(jù)key一一映射到對應的屬性中對數(shù)據(jù)進行賦值篷店,事實上使用只調用modelWithDictionary一個方法,剩下的YYModel會幫你處理里面的數(shù)據(jù),自動進行安全性判斷和值類型轉換疲陕。
2方淤、自定義屬性映射數(shù)據(jù)交換
YYModel支持自定義的屬性名進行映射,即數(shù)據(jù)的key和屬性名可以是不相同蹄殃。那么怎么才知道你自定義的屬性名對應的是數(shù)據(jù)的哪個key呢携茂?那就需要對自定義屬性的映射進行映射聲明。例如該例子中的personId:
// YYPersonModel.h
@interface YYPersonModel : NSObject

@property (strong, nonatomic) NSNumber *personId;
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) int age;
@property (copy, nonatomic) NSString *sex;

@end

在YYPersonModel.m 重寫yymodel的方法modelCustomPropertyMapper诅岩,返回設定的映射值,并且YYModel提供多個字段的映射讳苦。
// YYPersonModel.m

  • (NSDictionary *)modelCustomPropertyMapper {
    // 將personId映射到key為id的數(shù)據(jù)字段
    return @{@"personId":@"id"};
    // 映射可以設定多個映射字段
    // return @{@"personId":@[@"id",@"uid",@"ID"]};
    }

最后依然通過像原來的數(shù)據(jù)那樣,直接通過字典的方式進行模型轉換吩谦,當key為id時鸳谜,會自動給personId賦值,達到我們需要的效果式廷。
// ViewController.m
NSDictionary *dic = @{
@"id":@"123",
@"name":@"張三",
@"age":@(12),
@"sex":@"男"
};
YYPersonModel *model = [YYPersonModel modelWithDictionary:dic];
NSLog(@"ID: %@",model.personId);
NSDictionary *dics = [model modelToJSONObject];
NSLog(@"ID: %@", dics[@"id"]);

3咐扭、多樣化的數(shù)據(jù)類型交換
YYModel支持多樣化的數(shù)據(jù)類型,甚至字典滑废,數(shù)組等數(shù)據(jù)蝗肪,如果不存在,則該model會自動設置為null蠕趁,該例子提出使用NSArray和NSDictionary作為數(shù)據(jù)薛闪,效果依然一樣
// YYPersonModel.h
@interface YYPersonModel : NSObject

@property (strong, nonatomic) NSNumber *personId;
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) int age;
@property (copy, nonatomic) NSString *sex;
@property (strong, nonatomic) NSArray *languages;
@property (strong, nonatomic) NSDictionary *job;

@end

不得不說YYModel還是考慮很全面的,不僅支持各種類型數(shù)據(jù)妻导,甚至考慮到獲取到數(shù)據(jù)的層次關系并沒有那么完美,那么這個時候該怎么做呢怀各。例如該例子中的獲取到sex倔韭,是嵌套在下一層,同樣的我們也需要去聲明:
// YYPersonModel.m

  • (NSDictionary *)modelCustomPropertyMapper {
    return @{
    @"personId":@"id",
    @"sex":@"sexDic.sex" // 聲明sex字段在sexDic下的sex
    };
    }

在數(shù)據(jù)中依然可以找到NSArray和NSDictionary和sexDic下的sex字段并轉化為模型
// ViewController.m
NSDictionary *dic = @{
@"id":@"123",
@"name":@"張三",
@"age":@(12),
@"sexDic":@{@"sex":@"男"},
@"languages":@[
@"漢語",@"英語",@"法語"
],
@"job":@{
@"work":@"iOS開發(fā)",
@"eveDay":@"10小時",
@"site":@"軟件園"
}
};
YYPersonModel *model = [YYPersonModel modelWithDictionary:dic];

4瓢对、自定義類數(shù)據(jù)轉換
項目使用過程中寿酌,我們會涉及到多個model嵌套使用的情況,關于自定義類的聲明硕蛹,YYModel提供給我們另外一個方法modelContainerPropertyGenericClass醇疼。例如我們在屬性中定義了YYEatModel作為類型。
// YYPersonModel.h
@interface YYEatModel : NSObject

@property (copy, nonatomic)NSString *food;
@property (copy, nonatomic)NSString *date;

@end

@interface YYPersonModel : NSObject

@property (strong, nonatomic) NSNumber *personId;
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) int age;
@property (copy, nonatomic) NSString *sex;
@property (strong, nonatomic) NSArray *languages;
@property (strong, nonatomic) NSDictionary *job;
@property (strong, nonatomic) NSArray <YYEatModel *> *eats;

@end

使用modelContainerPropertyGenericClass對賦值的key進行聲明后法焰,可直接賦值秧荆。
// YYPersonModel.m

  • (NSDictionary *)modelCustomPropertyMapper {
    return @{
    @"personId":@"id",
    @"sex":@"sexDic.sex" // 聲明sex字段在sexDic下的sex
    };
    }
    // 聲明自定義類參數(shù)類型
  • (NSDictionary *)modelContainerPropertyGenericClass {
    // value使用[YYEatModel class]或YYEatModel.class或@"YYEatModel"沒有區(qū)別
    return @{@"eats" : [YYEatModel class]};
    }

// ViewController.m
NSDictionary *dic = @{
@"id":@"123",
@"name":@"張三",
@"age":@(12),
@"sexDic":@{@"sex":@"男"},
@"languages":@[
@"漢語",@"英語",@"法語"
],
@"job":@{
@"work":@"iOS開發(fā)",
@"eveDay":@"10小時",
@"site":@"軟件園"
},
@"eats":@[
@{@"food":@"西瓜",@"date":@"8點"},
@{@"food":@"烤鴨",@"date":@"14點"},
@{@"food":@"西餐",@"date":@"20點"}
]
};
YYPersonModel *model = [YYPersonModel modelWithDictionary:dic];
for (YYEatModel *eat in model.eats) {
NSLog(@"%@",eat.food);
}

5、YYModel數(shù)據(jù)的其他處理
在轉化過程中埃仪,YYModel提供了過濾的功能乙濒,可以將想要轉換的屬性或者不需要轉換的屬性加入到黑白名單中,通常不同時使用。
// YYPersonModel.m
// 黑白名單不同時使用
// 如果實現(xiàn)了該方法颁股,則處理過程中會忽略該列表內的所有屬性

  • (NSArray *)modelPropertyBlacklist {
    return @[@"sex", @"languages"];
    }
    // 如果實現(xiàn)了該方法么库,則處理過程中不會處理該列表外的屬性。
  • (NSArray *)modelPropertyWhitelist {
    return @[@"eats"];
    }

有時候轉換后的model并不是我們最終想要的甘有,這個情況轉換結束時YYModel提供了校驗的接口诉儒,可以在該接口中,校驗轉換的結果返回false則直接忽略該model亏掀,同時可以在該接口中處理轉換過程中忱反,不能處理的數(shù)據(jù)。
// YYPersonModel.m
// 當 JSON 轉為 Model 完成后幌氮,該方法會被調用缭受。

  • (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic {
    // 可以在這里處理一些數(shù)據(jù)邏輯,如NSDate格式的轉換
    return YES;
    }

// 當 Model 轉為 JSON 完成后该互,該方法會被調用米者。

  • (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic {
    return YES;
    }

最后在Model使用過程中,往往會遇到一個深拷貝的問題宇智,為了不改變原model的數(shù)據(jù)蔓搞,YYModel也提供了一個接口實現(xiàn)深拷貝。至于不懂深拷貝的同學可以先去網(wǎng)上了解一下
// ViewController.m
// 深拷貝model
YYPersonModel *model2 = [model modelCopy];

總結
到這里為止随橘,關于YYModel的詳細使用方法已經寫完喂分,基本上所有的使用場景都會在,如果有什么疑問可以給我留言机蔗。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末蒲祈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子萝嘁,更是在濱河造成了極大的恐慌梆掸,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牙言,死亡現(xiàn)場離奇詭異酸钦,居然都是意外死亡,警方通過查閱死者的電腦和手機咱枉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門卑硫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蚕断,你說我怎么就攤上這事欢伏。” “怎么了亿乳?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵颜懊,是天一觀的道長。 經常有香客問我,道長河爹,這世上最難降的妖魔是什么匠璧? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮咸这,結果婚禮上夷恍,老公的妹妹穿的比我還像新娘。我一直安慰自己媳维,他們只是感情好酿雪,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著侄刽,像睡著了一般指黎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上州丹,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天醋安,我揣著相機與錄音,去河邊找鬼墓毒。 笑死吓揪,一個胖子當著我的面吹牛,可吹牛的內容都是我干的所计。 我是一名探鬼主播柠辞,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼主胧!你這毒婦竟也來了叭首?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤踪栋,失蹤者是張志新(化名)和其女友劉穎焙格,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體己英,經...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡间螟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年吴旋,在試婚紗的時候發(fā)現(xiàn)自己被綠了损肛。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡荣瑟,死狀恐怖治拿,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情笆焰,我是刑警寧澤劫谅,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響捏检,放射性物質發(fā)生泄漏荞驴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一贯城、第九天 我趴在偏房一處隱蔽的房頂上張望熊楼。 院中可真熱鬧,春花似錦能犯、人聲如沸鲫骗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽执泰。三九已至,卻和暖如春渡蜻,著一層夾襖步出監(jiān)牢的瞬間术吝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工晴楔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留顿苇,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓税弃,卻偏偏與公主長得像纪岁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子则果,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內容