Runtime(字典转模型)学习

Runtime字典转模型思路:通过Runtime获取模型中的属性(对应字典中的key),通过属性去字典中取出对应的value,然后给模型的属性赋值。

Demo链接

// ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];

    NSDictionary *dict = @{
                           @"key1":@"value1",
                           @"key2":@"value2",
                           @"key3":@"value3",
                           @"modelTwo":@{
                                   @"key1":@"value1",
                                   @"key2":@"value2",
                                   @"key3":@"value3"
                                   }
                           };

    Model *model = [Model modelWithDict:dict];

}
// Model.h

#import <Foundation/Foundation.h>
#import "ModelTwo.h"

@interface Model : NSObject

@property (nonatomic,strong) NSString *key1;

@property (nonatomic,strong) NSString *key2;

@property (nonatomic,strong) NSString *key3;

@property (nonatomic,strong) ModelTwo *modelTwo;

@end

// ModelTwo.h

#import <Foundation/Foundation.h>

@interface ModelTwo : NSObject

@property (nonatomic,strong) NSString *key1;

@property (nonatomic,strong) NSString *key2;

@property (nonatomic,strong) NSString *key3;

@end

定义一个Category : NSObject+Model

// NSObject+Model.h

@interface NSObject (Model)

+ (instancetype)modelWithDict:(NSDictionary *)dict;

@end

// NSObject+Model.m

#import "NSObject+Model.h"
#import <objc/message.h>//引入Runtime

@implementation NSObject (Model)

+ (instancetype)modelWithDict:(NSDictionary *)dict
{
    id objc = [[self alloc] init];

    /**
     * Runtime字典转模型思路
     *
     * 通过Runtime获取模型中的属性(对应字典中的key),通过属性去字典中取出对应的value,然后给模型的属性赋值。
     */

    [self demo1];
    [self demo2];

    // 获取模型中的所有成员变量 key
    unsigned int count = 0;
    // 获取成员变量数组
    Ivar *ivarList = class_copyIvarList(self, &count);

    // 遍历所有成员变量
    for (int i = 0; i < count; i++) {
        // 获取成员变量
        Ivar ivar = ivarList[i];

        // 获取成员变量名
        NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)];

        // 获取成员变量类型
        NSString *ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
        // @\"ModelTwo\" -> ModelTwo
        ivarType = [ivarType stringByReplacingOccurrencesOfString:@"\"" withString:@""];
        ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""];

        // 获取key,截取掉下划线
        NSString *key = [ivarName substringFromIndex:1];

        id value = dict[key];

        //二级转换:判断value是不是字典,如果是字典,字典转换成ivarType对应的模型
        //自定义对象才需要转换(hasPrefix: 是包含前缀xx)
        if ([value isKindOfClass:[NSDictionary class]]
            && ![ivarType hasPrefix:@"NS"]) {
            // 获取该自定义类的类型
            Class modelClass = NSClassFromString(ivarType);
            // 将自身(dic)转换成自定义模型(modelTwo)
            value = [modelClass modelWithDict:value];
        }

        // 给模型中属性赋值
        if (value) {
            [objc setValue:value forKey:key];
        }
    }

    return objc;
}

//用于解释获取成员变量时,class_copyIvarList(self, &count)里的count值为何改变
- (void)demo1
{
    int count = 0;
    [self testDemo1:&count];

    NSLog(@"count:%d",count);
}

- (void)testDemo1:(int *)count
{
    *count = 1;
}

//解释为何Ivar *ivarList 是个数组
- (void)demo2
{
    int a = 1;
    int b = 2;
    int c = 3;
    int arr[] = {a,b,c};
    int *p = arr;

    NSLog(@"p[1]:%d p[2]:%d",p[1],p[2]);
}


@end

展示运行结果

Runtime字典转模型运行结果]

解释一个问题,为何使用Runtime获取成员变量而不是属性

Ivar:成员变量 Property:属性

@interface Model : NSObject{
    //成员变量
    NSString *_key3;
}

//属性
@property (nonatomic,strong) NSString *key1;

@property (nonatomic,strong) NSString *key2;

@property (nonatomic,strong) NSString *key3;

@property (nonatomic,strong) ModelTwo *modelTwo;

@end

定义属性时,会自动生成带成员变量。比如key1属性,会生成_key1成员变量。获取所有属性,有可能会漏掉成员变量。而获取成员变量,一定不会漏掉属性。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值