YYModel 的使用場景和詳解

前言

YYModel是YYKit的高效組件之一,在實(shí)際場景中的非常實(shí)用觉啊,運(yùn)用于項(xiàng)目中使用MVC或MVVM架構(gòu)時(shí)权埠,使用model做數(shù)據(jù)處理殖卑。

  • 自動(dòng)轉(zhuǎn)換模型數(shù)據(jù)
  • 自動(dòng)檢測數(shù)據(jù)安全性,避免carch
  • 無需繼承其他類倒源,使用方便
  • 適用model各種數(shù)據(jù)加載運(yùn)用場景

在使用之前先展示一些YYModel比較常用的方法苛预,后面會(huì)具體介紹用法

// 字典轉(zhuǎn)模型
+ (nullable instancetype)modelWithDictionary:(NSDictionary *)dictionary;
// json轉(zhuǎn)模型
+ (nullable instancetype)modelWithJSON:(id)json;
// 模型轉(zhuǎn)NSObject
- (nullable id)modelToJSONObject;
// 模型轉(zhuǎn)NSData
- (nullable NSData *)modelToJSONData;
// 模型轉(zhuǎn)json字符串
- (nullable NSString *)modelToJSONString;
// 模型深拷貝
- (nullable id)modelCopy;
// 判斷模型是否相等
- (BOOL)modelIsEqual:(id)model;
// 屬性數(shù)據(jù)映射,用來定義多樣化數(shù)據(jù)時(shí)轉(zhuǎn)換聲明
+ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper;
// 屬性自定義類映射笋熬,用來實(shí)現(xiàn)自定義類的轉(zhuǎn)換聲明
+ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass;
// 屬性黑名單热某,該名單屬性不轉(zhuǎn)換為model
+ (nullable NSArray<NSString *> *)modelPropertyBlacklist;
// 屬性白名單,只有該名單的屬性轉(zhuǎn)換為model
+ (nullable NSArray<NSString *> *)modelPropertyWhitelist;
// JSON 轉(zhuǎn)為 Model 完成后胳螟,該方法會(huì)被調(diào)用昔馋,返回false該model會(huì)被忽略
// 同時(shí)可以在該model中做一些,轉(zhuǎn)換不能實(shí)現(xiàn)的操作糖耸,如NSDate類型轉(zhuǎn)換
- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;
// Model 轉(zhuǎn)為 JSON 完成后秘遏,該方法會(huì)被調(diào)用,返回false該model會(huì)被忽略
// 同時(shí)可以在該model中做一些蔬捷,轉(zhuǎn)換不能實(shí)現(xiàn)的操作垄提,如NSDate類型轉(zhuǎn)換
- (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic

運(yùn)用場景

1、簡單的數(shù)據(jù)交換

YYModel最簡單的使用周拐,在正常的數(shù)據(jù)調(diào)用铡俐,創(chuàng)建一個(gè)model類YYPersonModel,增加幾個(gè)屬性妥粟。

// YYPersonModel.h
@interface YYPersonModel : NSObject

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

@end

接著在viewController導(dǎo)入<NSObject+YYModel.h>頭文件审丘,直接進(jìn)行賦值就可以了,數(shù)據(jù)類型可可以是JSON/Dictionary勾给,具體的可以看<NSObject+YYModel.h>給出的方法滩报。

// ViewController.m
NSDictionary *dic = @{
                      @"name":@"張三",
                      @"age":@(12),
                      @"sex":@"男"
                    };
// 將數(shù)據(jù)轉(zhuǎn)模型
YYPersonModel *model = [YYPersonModel modelWithDictionary:dic];
// 將模型轉(zhuǎn)數(shù)據(jù)
NSDictionary *dics = [model modelToJSONObject];

使用起來是不是變得特別方便锅知,會(huì)自動(dòng)根據(jù)key一一映射到對應(yīng)的屬性中對數(shù)據(jù)進(jìn)行賦值,事實(shí)上使用只調(diào)用modelWithDictionary一個(gè)方法脓钾,剩下的YYModel會(huì)幫你處理里面的數(shù)據(jù)售睹,自動(dòng)進(jìn)行安全性判斷和值類型轉(zhuǎn)換。

2可训、自定義屬性映射數(shù)據(jù)交換

YYModel支持自定義的屬性名進(jìn)行映射昌妹,即數(shù)據(jù)的key和屬性名可以是不相同。那么怎么才知道你自定義的屬性名對應(yīng)的是數(shù)據(jù)的哪個(gè)key呢握截?那就需要對自定義屬性的映射進(jìn)行映射聲明飞崖。例如該例子中的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,返回設(shè)定的映射值,并且YYModel提供多個(gè)字段的映射谨胞。

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

最后依然通過像原來的數(shù)據(jù)那樣固歪,直接通過字典的方式進(jìn)行模型轉(zhuǎn)換,當(dāng)key為id時(shí)胯努,會(huì)自動(dòng)給personId賦值牢裳,達(dá)到我們需要的效果。

// 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會(huì)自動(dòng)設(shè)置為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ù)的層次關(guān)系并沒有那么完美约巷,那么這個(gè)時(shí)候該怎么做呢。例如該例子中的獲取到sex旱捧,是嵌套在下一層独郎,同樣的我們也需要去聲明:

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

在數(shù)據(jù)中依然可以找到NSArray和NSDictionary和sexDic下的sex字段并轉(zhuǎn)化為模型

// ViewController.m
NSDictionary *dic = @{
                      @"id":@"123",
                      @"name":@"張三",
                      @"age":@(12),
                      @"sexDic":@{@"sex":@"男"},
                      @"languages":@[
                              @"漢語",@"英語",@"法語"
                              ],
                      @"job":@{
                              @"work":@"iOS開發(fā)",
                              @"eveDay":@"10小時(shí)",
                              @"site":@"軟件園"
                              }
                      };
YYPersonModel *model = [YYPersonModel modelWithDictionary:dic];
4、自定義類數(shù)據(jù)轉(zhuǎn)換

項(xiàng)目使用過程中枚赡,我們會(huì)涉及到多個(gè)model嵌套使用的情況氓癌,關(guān)于自定義類的聲明,YYModel提供給我們另外一個(gè)方法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進(jìn)行聲明后,可直接賦值卢肃。

// 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小時(shí)",
                              @"site":@"軟件園"
                              },
                      @"eats":@[
                              @{@"food":@"西瓜",@"date":@"8點(diǎn)"},
                              @{@"food":@"烤鴨",@"date":@"14點(diǎn)"},
                              @{@"food":@"西餐",@"date":@"20點(diǎn)"}
                              ]
                      };
YYPersonModel *model = [YYPersonModel modelWithDictionary:dic];
for (YYEatModel *eat in model.eats) {
    NSLog(@"%@",eat.food);
}
5疲迂、YYModel數(shù)據(jù)的其他處理

在轉(zhuǎn)化過程中才顿,YYModel提供了過濾的功能,可以將想要轉(zhuǎn)換的屬性或者不需要轉(zhuǎn)換的屬性加入到黑白名單中尤蒿,通常不同時(shí)使用郑气。

// YYPersonModel.m 
// 黑白名單不同時(shí)使用
// 如果實(shí)現(xiàn)了該方法,則處理過程中會(huì)忽略該列表內(nèi)的所有屬性
+ (NSArray *)modelPropertyBlacklist {
    return @[@"sex", @"languages"];
}
// 如果實(shí)現(xiàn)了該方法腰池,則處理過程中不會(huì)處理該列表外的屬性竣贪。
+ (NSArray *)modelPropertyWhitelist {
    return @[@"eats"];
}

有時(shí)候轉(zhuǎn)換后的model并不是我們最終想要的,這個(gè)情況轉(zhuǎn)換結(jié)束時(shí)YYModel提供了校驗(yàn)的接口巩螃,可以在該接口中演怎,校驗(yàn)轉(zhuǎn)換的結(jié)果返回false則直接忽略該model,同時(shí)可以在該接口中處理轉(zhuǎn)換過程中避乏,不能處理的數(shù)據(jù)爷耀。

// YYPersonModel.m 
// 當(dāng) JSON 轉(zhuǎn)為 Model 完成后,該方法會(huì)被調(diào)用拍皮。
- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic {
    // 可以在這里處理一些數(shù)據(jù)邏輯歹叮,如NSDate格式的轉(zhuǎn)換
    return YES;
}

// 當(dāng) Model 轉(zhuǎn)為 JSON 完成后,該方法會(huì)被調(diào)用铆帽。
- (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic {
    return YES;
}

最后在Model使用過程中咆耿,往往會(huì)遇到一個(gè)深拷貝的問題,為了不改變原model的數(shù)據(jù)爹橱,YYModel也提供了一個(gè)接口實(shí)現(xiàn)深拷貝萨螺。至于不懂深拷貝的同學(xué)可以先去網(wǎng)上了解一下

// ViewController.m
// 深拷貝model
YYPersonModel *model2 = [model modelCopy];

總結(jié)

到這里為止,關(guān)于YYModel的詳細(xì)使用方法已經(jīng)寫完愧驱,基本上所有的使用場景都會(huì)在慰技,如果有什么疑問可以給我留言。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末组砚,一起剝皮案震驚了整個(gè)濱河市吻商,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌糟红,老刑警劉巖艾帐,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異盆偿,居然都是意外死亡柒爸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門陈肛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來揍鸟,“玉大人,你說我怎么就攤上這事⊙粼澹” “怎么了晰奖?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長腥泥。 經(jīng)常有香客問我匾南,道長,這世上最難降的妖魔是什么蛔外? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任蛆楞,我火速辦了婚禮,結(jié)果婚禮上夹厌,老公的妹妹穿的比我還像新娘豹爹。我一直安慰自己,他們只是感情好矛纹,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布臂聋。 她就那樣靜靜地躺著,像睡著了一般或南。 火紅的嫁衣襯著肌膚如雪孩等。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天采够,我揣著相機(jī)與錄音肄方,去河邊找鬼。 笑死蹬癌,一個(gè)胖子當(dāng)著我的面吹牛权她,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播冀瓦,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼伴奥,長吁一口氣:“原來是場噩夢啊……” “哼写烤!你這毒婦竟也來了翼闽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤洲炊,失蹤者是張志新(化名)和其女友劉穎感局,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體暂衡,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡询微,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狂巢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撑毛。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖唧领,靈堂內(nèi)的尸體忽然破棺而出藻雌,到底是詐尸還是另有隱情雌续,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布胯杭,位于F島的核電站驯杜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏做个。R本人自食惡果不足惜鸽心,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望居暖。 院中可真熱鬧逗抑,春花似錦、人聲如沸砾层。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跟束。三九已至莺奸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間冀宴,已是汗流浹背灭贷。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留略贮,地道東北人甚疟。 一個(gè)月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像逃延,于是被迫代替她去往敵國和親览妖。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359