現(xiàn)在大家提起字典轉(zhuǎn)模型,都會(huì)想到使用MJExtension第三方庫(kù).這那里面封裝了很多的功能,確實(shí)非常方便好用, 但我現(xiàn)在的需求僅僅只是從json解析過(guò)來(lái)的數(shù)據(jù)傳值給我定義的modal,不需要用那么多功能,自然也就不想拖那么多多余的類(lèi)進(jìn)我的工程里面. 所以我就自定義了一個(gè)字典轉(zhuǎn)模型的分類(lèi)實(shí)現(xiàn)我這一簡(jiǎn)單的功能:
解決的問(wèn)題:當(dāng)json里的字段和Modal里的屬性名一致時(shí),可以直接用: - (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues; 當(dāng)不一致,如后臺(tái)又加了字段,刪或改了字段, 再用那個(gè)方法你運(yùn)行就直接崩潰了.我定義的這個(gè)分類(lèi)就是解決這個(gè)崩潰的問(wèn)題!
#pragma mark --取得類(lèi)中的所以屬性名
- (NSMutableArray *)getProperties:(Class)class
{
unsigned int count;
objc_property_t *properties = class_copyPropertyList(class, &count);
NSMutableArray * propertyArray = [NSMutableArray array];
for (int i = 0; i<count; i++) {
// objc_property_t 屬性類(lèi)型
objc_property_t property = properties[i];
// 獲取屬性的名稱 C語(yǔ)言字符串
const char *cName = property_getName(property);
// 轉(zhuǎn)換為Objective C 字符串
NSString *nameStr = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
[propertyArray addObject:nameStr];
}
return propertyArray;
}
#pragma mark -- 通過(guò)字符串來(lái)創(chuàng)建該字符串的Setter方法,并返回
- (SEL) creatSetterWithPropertyName: (NSString *) propertyName{
// 只把首字母變成大寫(xiě),其它的不變
NSString * firstStr = [propertyName substringToIndex:1];
NSString * secondStr = [propertyName substringFromIndex:1];
//1.首字母大寫(xiě)
firstStr = firstStr.capitalizedString;
//2.拼接上set關(guān)鍵字
propertyName = [NSString stringWithFormat:@"set%@%@:", firstStr,secondStr];
//3.返回set方法
return NSSelectorFromString(propertyName);
}
#pragma mark --利用傳入的字典給類(lèi)屬性賦值
- (instancetype) assginToPropertyWithDictionary: (NSDictionary *) data
{
if (data == nil) {
return nil;
}
// 獲取所有的屬性值
NSMutableArray * array = [self getProperties:[self class] ];
NSMutableDictionary * valueDictionary = [NSMutableDictionary dictionary];
NSMutableArray * propertyArray = [NSMutableArray array];
for (NSString * string in array) {
if ([[data allKeys] containsObject:string]) {
[valueDictionary setObject:data[string] forKey:string];
}else{
[propertyArray addObject:string];
}
}
///2.循環(huán)遍歷字典key, 并且動(dòng)態(tài)生成實(shí)體類(lèi)的setter方法,把字典的Value通過(guò)setter方法
///賦值給實(shí)體類(lèi)的屬性
for (int i = 0; i < valueDictionary.count; i ++) { //當(dāng)字典中鍵值比較多時(shí).
NSString * propertyStr = [valueDictionary allKeys][i];
///2.1 通過(guò)getSetterSelWithAttibuteName 方法來(lái)獲取實(shí)體類(lèi)的set方法
SEL setSel = [self creatSetterWithPropertyName:propertyStr];
if ([self respondsToSelector:setSel]) {
///2.2 獲取字典中key對(duì)應(yīng)的value
NSString *value = [NSString stringWithFormat:@"%@", valueDictionary[propertyStr]];
///2.3 把值通過(guò)setter方法賦值給實(shí)體類(lèi)的屬性
[self performSelectorOnMainThread:setSel
withObject:value
waitUntilDone:[NSThread isMainThread]];
}
}
for (int i = 0; i<propertyArray.count; i++) { //當(dāng)類(lèi)屬性比較多時(shí)
SEL setSel = [self creatSetterWithPropertyName:propertyArray[i]];
if ([self respondsToSelector:setSel]) {
///2.2 獲取字典中key對(duì)應(yīng)的value
NSString * str = @"";
NSString *value = [NSString stringWithFormat:@"%@", str];
///2.3 把值通過(guò)setter方法賦值給實(shí)體類(lèi)的屬性
[self performSelectorOnMainThread:setSel
withObject:value
waitUntilDone:[NSThread isMainThread]];
}
}
return self;
}
建個(gè)NSObject的分類(lèi),定一個(gè)類(lèi)方法.
+ (instancetype)valueWithDictionary:(NSDictionary *)dict
{
return [[self alloc] assginToPropertyWithDictionary:dict];
}
搞定,針對(duì)模型類(lèi)屬性與json字段不一致的情況,直接將這個(gè)分類(lèi)拖進(jìn)去,調(diào)用類(lèi)方法,既能傳值,又不會(huì)導(dǎo)致崩潰的情況!