您当前的位置: 首页 > 

white camel

暂无认证

  • 0浏览

    0关注

    442博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Runtime 一一 runtime实现字典转模型,多级转换.

white camel 发布时间:2018-01-26 17:42:36 ,浏览量:0

请先看上篇博客: KVC实现字典转模型

思路: 利用运行时,取出模型中所有的属性,根据模型的属性名,去字典中查找对应的key,然后给模型中的属性赋值.

实现: 提供一个NSObject分类,专门用来字典转模型,以后所有的模型都可以通过这个分类来转.

知识点:

① 给NSObject写一个分类,专门用来 字典转模型

② 成员变量和属性的区别

 1. 例如 @property NSString *name; 此时name就是属性

 2. 属性name生成_name 就是 成员变量

③  利用runtime获得模型中成员变量的数组,遍历成员变量数组,取出模型中所有的成员变量,并转为字符串,并且去掉下划线.就是属性名.

/*
     param1:Class 获取哪个类的成员变量
     param2:count 成员变量个数
     */
    unsigned int count = 0;
    // Ivar 是一个成员变量数组
    Ivar *ivarList = class_copyIvarList(self, &count);
    // 遍历
    for (int i = 0; i < count; ++i) {
        // 获取成员变量
        Ivar ivar = ivarList[i];
        // 获取成员变量名字
        NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)];
        //NSLog(@"%@",ivarName);
        
        // 获取成员变量的类型
        NSString *ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
        // NSLog(@"%@",ivarType); //@"ZYUserItem"
        ivarType = [ivarType stringByReplacingOccurrencesOfString:@"\"" withString:@""];
        ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""];
        // NSLog(@"%@",ivarType); // ZYUserItem
        
        // 获取key
        NSString *key = [ivarName substringFromIndex:1];

④ 根据属性名去字典中查找value

⑤给模型中的属性赋值(KVC) setValue:forKey:

ViewController文件

//  Created by 朝阳 on 2018/1/23.
//  Copyright © 2018年 sunny. All rights reserved.
//

#import "ViewController.h"
#import "NSDictionary+Property.h"
#import "ZYStatusItem.h"
#import "NSObject+Model.h"
#import "ZYUserItem.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //1. 加载plist文件
    // 获取文件全路径
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"status.plist" ofType:nil];
    
    // 文件全路径
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath];
    
    // 设置模型,创建属性代码 ==> dict
    //[dict[@"user"] createPropertyCode]; // 自动生成属性
    
    // 字典转模型
    ZYStatusItem *item = [ZYStatusItem modelWithDict:dict];
    ZYUserItem *userItem = item.user;
    NSLog(@"%@",userItem.name);
    
}
@end
NSObject+Model文件

#import "NSObject+Model.h"
#import 

@implementation NSObject (Model)

/*
 获取类里面所有方法
 class_copyMethodList(Class  _Nullable __unsafe_unretained cls, unsigned int * _Nullable outCount)
 // Property 属性
 class_copyPropertyList(Class  _Nullable __unsafe_unretained cls, unsigned int * _Nullable outCount)
 // Ivar 成员变量 _开头
 class_copyIvarList(Class  _Nullable __unsafe_unretained cls, unsigned int * _Nullable outCount)
 */

// 本质:创建谁的对象
// 字典转模型
+ (instancetype)modelWithDict:(NSDictionary *)dict
{
    id objc = [[self alloc] init];
    
    // runtime:根据模型中的属性,去字典中取出对应的key, 然后给模型属性赋值
    //1.获取模型中所有属性 key
    /*
     param1:Class 获取哪个类的成员变量
     param2:count 成员变量个数
     */
    unsigned int count = 0;
    // Ivar 是一个成员变量数组
    Ivar *ivarList = class_copyIvarList(self, &count);
    // 遍历
    for (int i = 0; i < count; ++i) {
        // 获取成员变量
        Ivar ivar = ivarList[i];
        // 获取成员变量名字
        NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)];
        //NSLog(@"%@",ivarName);
        
        // 获取成员变量的类型
        NSString *ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
        // NSLog(@"%@",ivarType); //@"ZYUserItem"
        ivarType = [ivarType stringByReplacingOccurrencesOfString:@"\"" withString:@""];
        ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""];
        // NSLog(@"%@",ivarType); // ZYUserItem
        
        // 获取key
        NSString *key = [ivarName substringFromIndex:1];
        //2.根据属性名去字典中查找value
        id value = dict[key];
        // 二级转换:判断下value是否是字典,如果是,字典转为对应的模型
        // 并且是自定义对象的字典才需要转换: 成员变量的类型前缀不是NS.
        if ([value isKindOfClass:[NSDictionary class]] && ![ivarType hasPrefix:@"NS"]) {
            // 字典转模型 => userDict => User模型
            
            //1. 获取哪个类型?
            // 获取成员变量的类型
//            NSString *ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
//            // NSLog(@"%@",ivarType); //@"ZYUserItem"
//            ivarType = [ivarType stringByReplacingOccurrencesOfString:@"\"" withString:@""];
//            ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""];
//            // NSLog(@"%@",ivarType); // ZYUserItem
//
            //2. 获取哪个类
            Class modelClass = NSClassFromString(ivarType);
            value = [modelClass modelWithDict:value];
            
        }
        //3.给模型中属性赋值 KVC
        if (value) {
            [objc setValue:value forKey:key];
        }
    }
    
    return objc;
}

//void test (int *count)
//{
//    *count = 3;
//}

@end
ZYUserItem文件
#import 

@interface ZYUserItem : NSObject

@property (nonatomic, strong) NSString *profile_image_url;

@property (nonatomic, assign) BOOL vip;

@property (nonatomic, strong) NSString *name;

@property (nonatomic, assign) NSInteger mbrank;

@property (nonatomic, assign) NSInteger mbtype;

@end

关注
打赏
1661428283
查看更多评论
立即登录/注册

微信扫码登录

0.0367s