作品鏈接:http://www.itdecent.cn/users/1e0f5e6f73f6/top_articles
1 自動(dòng)打印屬性字符串分類
- 提供一個(gè)分類,專門(mén)根據(jù)字典生成對(duì)應(yīng)的屬性字符串。
@implementation NSObject (Property)
+ (void)PH_createPropertyCodeWithDict:(NSDictionary *)dict
{
NSMutableString *strM = [NSMutableString string];
// 遍歷字典
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull propertyName, id _Nonnull value, BOOL * _Nonnull stop) {
NSLog(@"%@,%@",propertyName,[value class]);
NSString *code;
if ([value isKindOfClass:NSClassFromString(@"__NSCFString")]) {
code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSString *%@;",propertyName]
;
} else if ([value isKindOfClass:NSClassFromString(@"__NSCFNumber")]){
code = [NSString stringWithFormat:@"@property (nonatomic, assign) int %@;",propertyName]
;
}else if ([value isKindOfClass:NSClassFromString(@"__NSCFArray")]){
code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSArray *%@;",propertyName]
;
}else if ([value isKindOfClass:NSClassFromString(@"__NSCFDictionary")]){
code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSDictionary *%@;",propertyName]
;
} else if ([value isKindOfClass:NSClassFromString(@"__NSCFBoolean")]){
code = [NSString stringWithFormat:@"@property (nonatomic, assign) BOOL %@;",propertyName]
;
}
[strM appendFormat:@"\n%@\n",code];
}];
NSLog(@"%@",strM);
}
@end
2 字典轉(zhuǎn)模型的方式一:KVC
@implementation Status
+ (instancetype)statusWithDict:(NSDictionary *)dict
{
Status *status = [[self alloc] init];
[status setValuesForKeysWithDictionary:dict];
return status;
}
@end
- KVC字典轉(zhuǎn)模型弊端:必須保證,模型中的屬性和字典中的key一一對(duì)應(yīng)。
- 如果不一致,就會(huì)調(diào)用
[<Status 0x7fa74b545d60> setValue:forUndefinedKey:]
報(bào)key找不到的錯(cuò)。 - 分析:模型中的屬性和字典的key不一一對(duì)應(yīng),系統(tǒng)就會(huì)調(diào)用
setValue:forUndefinedKey:報(bào)錯(cuò)。 - 解決:重寫(xiě)對(duì)象的
setValue:forUndefinedKey:,把系統(tǒng)的方法覆蓋,
就能繼續(xù)使用KVC,字典轉(zhuǎn)模型了。
- 如果不一致,就會(huì)調(diào)用
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
}
3 字典轉(zhuǎn)模型的方式二:Runtime
- KVC:遍歷字典中所有key,去模型中查找有沒(méi)有對(duì)應(yīng)的屬性名
- runtime:遍歷模型中所有屬性名,去字典中查找
1.思路與步驟
<!--* 思路:利用運(yùn)行時(shí),遍歷模型中所有屬性,根據(jù)模型的屬性名,去字典中查找key,取出對(duì)應(yīng)的值,給模型的屬性賦值。-->
<!--* 步驟:提供一個(gè)NSObject分類,專門(mén)字典轉(zhuǎn)模型,以后所有模型都可以通過(guò)這個(gè)分類轉(zhuǎn)。-->
2.分類
+ (instancetype)PH_modelWithDict:(NSDictionary *)dict
{
// 創(chuàng)建對(duì)應(yīng)類的對(duì)象
id objc = [[self alloc] init];
// runtime:遍歷模型中所有成員屬性,去字典中查找
// 屬性定義在哪,定義在類,類里面有個(gè)屬性列表(數(shù)組)
// 遍歷模型所有成員屬性
// ivar:成員屬性
// class_copyIvarList:把成員屬性列表復(fù)制一份給你
// Ivar *:指向Ivar指針
// Ivar *:指向一個(gè)成員變量數(shù)組
// class:獲取哪個(gè)類的成員屬性列表
// count:成員屬性總數(shù)
unsigned int count = 0;
Ivar *ivarList = class_copyIvarList(self, &count);
for (int i = 0; i < count; i++) {
// 獲取成員屬性
Ivar ivar = ivarList[i];
// 獲取成員名
NSString *propertyName = [NSString stringWithUTF8String:ivar_getName(ivar)];
//成員屬性類型
NSString *propertyType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
//獲取key
NSString *key = [propertyName substringFromIndex:1];
//獲取字典的value
id value = dict[key];
// 給模型的屬性賦值
// value:字典的值
// key:屬性名
// user:NSDictionary
//** '二級(jí)轉(zhuǎn)換'**
// 值是字典,成員屬性的類型不是字典,才需要轉(zhuǎn)換成模型
if ([value isKindOfClass:[NSDictionary class]] && ![propertyType containsString:@"NS"]) {
// 需要字典轉(zhuǎn)換成模型
// 轉(zhuǎn)換成哪個(gè)類型
// @"@\"User\"" User
NSRange range = [propertyType rangeOfString:@"\""];
propertyType = [propertyType substringFromIndex:range.location + range.length];
// User\"";
range = [propertyType rangeOfString:@"\""];
propertyType = [propertyType substringFromIndex:range.location];
// 字符串截取
// 獲取需要轉(zhuǎn)換類的類對(duì)象
Class modelClass = NSClassFromString(propertyType);
if (modelClass) {
value = [modelClass PH_modelWithDict:value];
}
}
<!-- 三級(jí)轉(zhuǎn)換:NSArray中也是字典,把數(shù)組中的字典轉(zhuǎn)換成模型.-->
// 判斷值是否是數(shù)組
if ([value isKindOfClass:[NSArray class]]) {
//判斷對(duì)應(yīng)類有沒(méi)有實(shí)現(xiàn)字典數(shù)組轉(zhuǎn)模型數(shù)組的協(xié)議
if ([self respondsToSelector:@selector(PH_arrayContainModelClass)]) {
// 轉(zhuǎn)換成id類型,就能調(diào)用任何對(duì)象的方法
id idSelf = self;
// 獲取數(shù)組中字典對(duì)應(yīng)的模型
NSString *type = [idSelf PH_arrayContainModelClass][key];
// 生成模型
Class classModel = NSClassFromString(type);
NSMutableArray *arrM = [NSMutableArray array];
// 遍歷字典數(shù)組,生成模型數(shù)組
for (NSDictionary *dict in value) {
// 字典轉(zhuǎn)模型
id model = [classModel PH_modelWithDict:dict];
[arrM addObject:model];
}
// 把模型數(shù)組賦值給value
value = arrM;
}
}
if (value) {
// kvc賦值:不能傳空
[objc setValue:value forKey:key];
}
NSLog(@"%@",key);
NSLog(@"%@,%@",propertyName,propertyType);
}
return objc;
}
3.轉(zhuǎn)換
- (void)viewDidLoad {
[super viewDidLoad];
// 解析
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"status.plist" ofType:nil];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath];
NSArray *dictArr = dict[@"statuses"];
// 設(shè)計(jì)模型屬性代碼
NSMutableArray *statuses = [NSMutableArray array];
for (NSDictionary *dict in dictArr) {
// 字典轉(zhuǎn)模型
Status *status = [Status PH_modelWithDict:dict];
[statuses addObject:status];
}
NSLog(@"%@",statuses);
}