基本原理利用 runtime 原理,獲取模型中所有實(shí)例變量列表,根據(jù)實(shí)例變量以此獲取模型中成員變量的名稱和屬性類型,區(qū)分Foundation和自定義屬性,需要對NSDictionary和NSArray類型做單獨(dú)處理。 下面代碼是一個(gè)簡單的原理實(shí)現(xiàn)Demo,真正的框架中需要考慮很多問題,例如可以設(shè)置只有某個(gè)數(shù)組中的屬性名才允許進(jìn)行字典和模型的轉(zhuǎn)換,將屬性名換為其他key去字典中取值,白名單,黑名單等等設(shè)置
+ (instancetype)modelWithDict:(NSDictionary *)dict { id objc = [[self alloc] init]; unsigned int count = 0; Ivar *ivarList = class_copyIvarList(self, &count); for (int i = 0; i < count; i++) { // 實(shí)例變量 Ivar ivar = ivarList[i]; // 獲取成員屬性名 NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)]; NSString *key = [ivarName substringFromIndex:1]; id value = dict[key]; if (value == nil) { continue; } // 獲得成員變量的類型 NSString *ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)]; NSLog(@"ivar - %@, type - %@", ivarName, ivarType); ivarType = [ivarType stringByReplacingOccurrencesOfString:@"\"" withString:@""]; ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""]; if ([value isKindOfClass:[NSDictionary class]]) { Class modelClass = NSClassFromString(ivarType); value = [modelClass modelWithDict:value]; } else if ([value isKindOfClass:[NSArray class]]) { if ([self respondsToSelector:@selector(arrayContainModelClass)]) { NSString *type = [self arrayContainModelClass][key]; Class classModel = NSClassFromString(type); NSMutableArray *arrM = [NSMutableArray array]; for (NSDictionary *dict in value) { id model = [classModel modelWithDict:dict]; if (model) { [arrM addObject:model]; } } value = arrM; } } if (value) { [objc setValue:value forKey:key]; } } return objc; }
常用的 JSON 模型轉(zhuǎn)換庫
性能、易用性,無浸入性根據(jù) ibireme 的測試結(jié)果:
|
|