runtime 字典转model

想着归档,想着model,突然想到其实我们平常字典转model 的需求其实是更常见的,因此此处也继续笔记下。

依然是先从最原始的字典转model,当然我们有时用 字典快速赋值 是最直接的。

- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues; 

然而有时,我们还是得类似下面这样:

#import <Foundation/Foundation.h>

@interface UserModel : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;

- (instancetype)initWithDictionary:(NSDictionary *)dictionary;

@end

#import "UserModel.h"

NSString *const kNameKey = @"name";
NSString *const kAgeKey = @"age";

@implementation UserModel

- (instancetype)initWithDictionary:(NSDictionary *)dictionary {
    self = [super init];
    if (self) {
        self.name = dictionary[kNameKey];
        self.age = [dictionary[kAgeKey] integerValue];
    }
    return self;
}

依然还是那种需求,当属性特别多的时候,我们就可以用 rumtime 进行字典转model 就简化啦

#import <Foundation/Foundation.h>

@interface TestModel : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, strong) NSDictionary * testDic;
@property (nonatomic, strong) NSArray * testArray;

- (instancetype)initWithDictionary:(NSDictionary *)dictionary;

@end

#import "TestModel.h"
#import <objc/runtime.h>
#import <objc/message.h>

@implementation TestModel

- (instancetype)initWithDictionary:(NSDictionary *)dictionary {
    self = [super init];
    if (self) {
        NSMutableArray * keyArray = [NSMutableArray array];
        unsigned  int outCount = 0 ;
        //获取该类的属性列表 class_copyPropertyList
        objc_property_t * propertys = class_copyPropertyList([self  class], &outCount);
        
        for (int i = 0 ; i < outCount; i++) {
            objc_property_t    property =  propertys[i];
            //获取属性对应的名称 property_getName
            NSString * propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
            [keyArray addObject:propertyName];
        }
        //记得要释放
        free(propertys);
        
        for (NSString * key in keyArray) {
            NSArray * keyArray = [dictionary allKeys];
            // 先做一个判断
            if (![keyArray containsObject:key]||[dictionary valueForKey:key] == nil) {
                continue ;
            }
            [self setValue:[dictionary valueForKey:key] forKey:key];
        }
    }
    return self;
}

经过测试是OK的

NSDictionary *testReusltDic = @{@"name":@"Yang",
                                    @"age":@"6",
                                    @"testArray":@[@"1",@"2"],
                                    @"testDic":@{@"one":@"1",@"two":@"2"}};
TestModel * model = [[TestModel alloc] initWithDictionary:testReusltDic];
NSLog(@"name ==== %@, age == %ld, testDic===%@, testArray === %@",model.name,model.age,model.testDic,model.testArray);
// output: name ==== Yang, age == 6, testDic==={one = 1;two = 2;}, testArray === (1, 2)

当然model 也可以通过runtime 转换成字典的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 对于从事 iOS 开发人员来说,所有的人都会答出【runtime 是运行时】什么情况下用runtime?大部分人能...
    梦夜繁星阅读 3,732评论 7 64
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,242评论 25 708
  • 一、专业分析 本人目前研究生阶段的专业是信息与通信工程。该专业是一个基础知识面宽、应用领域广阔的综合性专业,涉及无...
    波塞冬的鱼阅读 2,654评论 14 42
  • 《醒来,睡去》 醒来再次睡去就是这么自由 有人说有人问这算不算自由 想着你想着你每天总要几次 重复着重复着醒来再次...
    葉威阅读 356评论 0 3
  • 今天跟随集团的几位老师一起外出学习,大家凑在一起坐卧铺,有说有笑很热闹,大家在一起交流感觉收获不小。尤其一位老师谈...
    digman阅读 167评论 0 0