首页 > 代码库 > 利用runtime实现更加灵活的KVC

利用runtime实现更加灵活的KVC

   字典转模型在iOS开发中属于非常常见的操作.

   比较简单的方式是 KVC ,但是这样会有一个局限 ,就是 模型中的属性必须和字典中的完全匹配,否则,KVC将会报错.

   手动编写代码虽然比较灵活,但是如果字典中数据量庞大,也会是一个糟糕的体验.

   针对以上问题,利用runtime实现一个更加灵活的字典转模型.


  1.为 NSObject建立一个分类

    NSObject+GQRuntimeTool.h文件

#import <Foundation/Foundation.h>

@interface NSObject (GQRuntimeTool)

-(void)objectWithDictionary:(NSDictionary*)dict;

@end
  NSObject+GQRuntimeTool.m文件

#import "NSObject+GQRuntimeTool.h"
#import <objc/runtime.h>
#import <objc/message.h>

@implementation NSObject (GQRuntimeTool)


-(void)objectWithDictionary:(NSDictionary*)dict
{
    Class cls = [self class];
    unsigned int count;
    //Ivar instance variable 就是类的成员属性
    //通过运行时函数 获得 类内部的成员属性个数 放到 count 的地址
    //返回说是一个指针 ,所指向的内存空间为 首个 Ivar 的内存地址,这个相当于数组名
    Ivar *ivarArr = class_copyIvarList(cls, &count);
    //遍历数组( 数组名存放的是数组首地址,就是一个指针)
    for(int i =0;i<count;i++)
    {
        //把 Ivar 当成一个基本类型 比如 double 或者 int
        Ivar ivar = ivarArr[i];
        //获取属性名
        const char* name = ivar_getName(ivar);
        //获取属性类型
        NSString* typeName =[NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
      
        NSLog(@"%@",typeName); //发现 int 的类型是 i
        
        //1.将 c 字符串转换成 OC 的
        NSMutableString * ocVaribaleName = [NSMutableString stringWithUTF8String:name];
        //2.删除前面的  _
        [ocVaribaleName deleteCharactersInRange:NSMakeRange(0, 1)]; //    id_str
        //3.从字典取值的时候,使用的 key
        NSString *key = [ocVaribaleName copy];
        //4.取值
        id value = http://www.mamicode.com/dict[key];>
2. 模型对象

GQModel.h

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

@interface GQModel : NSObject
/**
 *  唯一标识符
 */
@property (nonatomic,copy)NSString *id_str;
/**
 *  姓名
 */
@property (nonatomic,copy)NSString *name;
/**
 *  年龄
 */
@property (nonatomic,assign)int age;
/**
 *  性别
 */
@property (nonatomic,copy)NSString *sex_str;


@end

.m文件无内容


3.在controller中

- (void)viewDidLoad
{
    [super viewDidLoad];
   
  //这个字典在实际工作中,都是来自 JSon对象的,此处仅仅供测试
   NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
                         @"22",@"id_str",
                         @33,@"age",
                         @"Grace",@"name",
                         @"male",@"sex_str",
                         nil];
    
    GQModel * mo = [[GQModel alloc]init];
    [mo objectWithDictionary:dict];
   
    if (mo) {
        NSLog(@"mo的id是:%@\n",mo.id_str);
        NSLog(@"mo的名字是:%@\n",mo.name);
        NSLog(@"mo的年龄是:%d\n",mo.age);
        NSLog(@"mo的性别是:%@\n",mo.sex_str);
        
    }
    
}

运行打印结果如下:


如果以后字典数据发生变化,只需要修改模型中的属性名即可.

是不是非常简单呢?





利用runtime实现更加灵活的KVC