经常遇到这样情况,当你从后台拿到数据,字典类型,里面有很多字段,多的时候,可能会几十个,这个时候,字段转换到模型,模型类的几十个字段,你要一个一个为其塞值么?我们就是这样干的。但是,总感觉代码很傻。
好了,现在可以这样:动态获取模型类的所有属性,然后用字典里面的值为其塞值。
这里用到了运行时,运行时,直到运行时才编译。
一、扩展NSArray分类
NSArray+Extension.h:
#import <Foundation/Foundation.h>
@interface NSArray (Extension)
+ (instancetype)getProperties:(Class)cls;
@end
NSArray+Extension.m:
#import "NSArray+Extension.h"
#import <objc/runtime.h>// 导入运行时文件
@implementation NSArray (Extension)
//返回当前类的所有属性
+ (instancetype)getProperties:(Class)cls{
// 获取当前类的所有属性
unsigned int count;// 记录属性个数
objc_property_t *properties = class_copyPropertyList(cls, &count);
// 遍历
NSMutableArray *mArray = [NSMutableArray array];
for (int i = 0; i < count; i++) {
// An opaque type that represents an Objective-C declared property.
// objc_property_t 属性类型
objc_property_t property = properties[i];
// 获取属性的名称 C语言字符串
const char *cName = property_getName(property);
// 转换为Objective C 字符串
NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
[mArray addObject:name];
}
return mArray.copy;
}
@end
二、定义模型类
假设模型类为 CZLoopImage,则
CZLoopImage.h
#import <Foundation/Foundation.h>
@interface CZLoopImage : NSObject
// 定义了下面两个属性,示例用,实际开发中有可能会几十个属性
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *imgsrc;
+ (instancetype)loopImage:(NSDictionary *)dic;
CZLoopImage.m
#import "CZLoopImage.h"
#import "NSArray+Extension.h"
@implementation CZLoopImage
+ (instancetype)loopImage:(NSDictionary *)dic{
id loopImage = [self new];
//获取所有属性 ,遍历 给属性赋值
NSArray *names = [NSArray getProperties:[self class]];// #import "NSArray+Extension.h" 使用分类
for (NSString *name in names) {
//如果字典中的值为空,赋值可能会出问题
if (dic[name]) {
[loopImage setValue:dic[name] forKey:name];
}
}
return loopImage;
}
NSArray+Extension可以多处重用,这样,从后台拿到数据,字典转模型,代码写得就优雅多了。
参考: