Runtime字典转模型是iOS开发中常用的一个数据转化的方法,其核心是利用runtime消息转发机制,利用objc_msgSend函数进行方法调用从而达到目的
其好处就是:
第一高效
第二可以随意增加属性,不用再用在.m中去写东西
第三对于任何模型通用,具有通用性
具体代码实现、实现方法的思路及代码如下:
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Person : NSObject
@property(nonatomic, copy) NSString *name;
@property(nonatomic, copy) NSString *age;
@property(nonatomic, copy) NSString *height;
@property(nonatomic, copy) NSString *phone;
//json转Model
-(instancetype)initWithDictToModel:(NSDictionary *)dict;
-(NSDictionary *)modelToDict;
@end
NS_ASSUME_NONNULL_END
#import "Person.h"
#import <objc/runtime.h>
#import <objc/message.h>
@implementation Person
//通过runtime实现快速的字典转模型的方法
-(instancetype)initWithDictToModel:(NSDictionary *)dict{
self = [super init];
if (self) {
//将字典的所有key遍历出来进行setter方法赋值
for (NSString *key in dict) {
//第一步:根据keys去写它的setter方法
NSString *keySetter = [NSString stringWithFormat:@"set%@:",key.capitalizedString];
SEL sel = NSSelectorFromString(keySetter);
//第二步:拿到key所对应的value 因为可能回事bool int long nsstring,所以用id接收
id value = dict[key];
//接着就是实现setter方法了
if (sel) {
//因为objc_msgSend 需要做一个函数指针的强转 void 是因为objc_msgSend 无返回值
((void(*)(id,SEL,id))objc_msgSend)(self, sel, value);
}
}
}
return self;
}
//通过getter方法去获取它的值 放到字典中
-(NSDictionary *)modelToDict{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
//
unsigned int count = 0;
// An opaque type that represents an Objective-C declared property.获取声明的属性列表
//但是要注意,凡是使用到class_copy...都需要free()释放;
objc_property_t *propertys = class_copyPropertyList(NSClassFromString(@"Person"),&count);
if (count == 0) {
return nil;
}
//遍历它的属性列表,按钮字典转模型的方法,写一个getter方法,获取值
for (int i = 0; i< count; i++) {
//第一步:获取属性值
//property_getName 返回的是一个C string ,此时我们用遍历的方式,就要用指针接收,然后根据指针移动获取他的属性值
const char *propertyName = property_getName(propertys[i]);
NSString *name = [NSString stringWithUTF8String:propertyName];
SEL sel = NSSelectorFromString(name);
if (sel) {
id value = ((id(*)(id,SEL))objc_msgSend)(self, sel);
//这个地方加一个判空处理,可以直接用到项目中去
if (value) {
[dict setObject:value forKey:name];
}else{
[dict setObject:@"" forKey:name];
}
}
}
free(propertys);
return dict;
}
在控制器ViewController的调用如下:
//model ---> dict
Person *per = [[Person alloc]initWithDictToModel:@{@"name":@"yg",@"age":@"123",@"height":@"180",@"phone":@"199999989898",}];
NSLog(@"==== persn.name = %@",per.name);
//dict ---> model
NSDictionary *item = [per modelToDict];
NSLog(@"======== %@ ========",item);
网友评论