iOS 利用KVC进行数据转模型

前言

最近公司要求做一个SDK供三方使用,在制作过程中就碰到一个问题,因为要进行网络请求获取数据,并且为了避免冲突要尽量不使用三方框架,所以平时常用的数据转模型框架MJExtension就没有使用,而是用系统的KVC进行简单处理,为什么数据要转模型,这个就不多陈述了,好处不言而喻。

KVC

KVC的介绍可以参考iOS开发技巧系列---详解KVC(我告诉你KVC的一切)文章讲的很详细,下面我们进入我们的主题

普通model

我们先来看一个普通DogModel类

//DogModel.h
#import 

@interface DogModel : NSObject
@property (nonatomic, copy) NSString *pid;//id
@property (nonatomic, copy) NSString *name;//名子
@property (nonatomic, assign) int age;//年龄
//初始化方法
- (instancetype)initWithDictionary:(NSDictionary *)dic;
@end
//DogModel.m
#import "DogModel.h"

@implementation DogModel
- (instancetype)initWithDictionary:(NSDictionary *)dic{
    if (self = [super init]){
        [self setValuesForKeysWithDictionary:dic];
    }
    return self;
}

- (void)setValue:(id)value forKey:(NSString *)key{
    //在这里更改key
    if([key isEqualToString:@"id"]){
        key = @"pid";
    }
    [super setValue:value forKey:key];
}
//冗错处理,如果有未定义的字段的话就会走到这里,不重写的话会引起崩溃
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
    NSLog(@"value:%@,undefineKey:%@",value,key);
}
@end
  • 我们在进行数据转模型时最重要的一个方法就是 setValuesForKeysWithDictionary
    他会遍历字典中的每一个key,然后进行赋值,
  • 你可以在- (void)setValue:(id)value forKey:(NSString *)key这个方法中监听到每一个key,有时候后台命名不符合我们或者是一个关键字,那么这时候就要把这个key值进行转换,例如:这里将id->pid;
  • 方法- (void)setValue:(id)value forUndefinedKey:(NSString *)key 如果key在model中没有定义,则会走到这里,要不然会崩溃,所以这个方法必须重写。
  • 实现效果,未定义的key打印了出来,model也赋值成功


    普通model测试

带有NSArray的model

先看下我们的PersonModel类

//PersonModel.h
#import 
#import "DogModel.h"

@interface PersonModel : NSObject
@property (nonatomic, copy) NSString *name;
//是否是小孩(<14岁)
@property (nonatomic, assign) BOOL isChild;
//性别(0-男 1-女)
@property (nonatomic, assign) int sex;
//男/女(根据sex进行处理后的结果)
@property (nonatomic, copy) NSString *sexStr;
//拥有的Dog(数组)
@property (nonatomic, strong) NSArray  *dogs;

//初始化方法
- (instancetype)initWithDictionary:(NSDictionary *)dic;
@end

//PersonModel.m
#import "PersonModel.h"
@implementation PersonModel
- (instancetype)initWithDictionary:(NSDictionary *)dic{
    if (self = [super init]){
        [self setValuesForKeysWithDictionary:dic];
    }
    return self;
}

- (void)setValue:(id)value forKey:(NSString *)key{
    //在这里处理数组转换
    if([key isEqualToString:@"dogs"]){
        NSMutableArray *array = [NSMutableArray array];
        for (NSDictionary *dic in value){
            DogModel *model = [[DogModel alloc] initWithDictionary:dic];
            [array addObject:model];
        }
        //注意这个地方不能用变量名dogs,一定要用value,不然转换后的模型则没有赋值进去
        value = array;
    }
    [super setValue:value forKey:key];
}
//冗错处理,如果有未定义的字段的话就会走到这里,不重写的话会引起崩溃
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
    NSLog(@"value:%@,undefineKey:%@",value,key);
}

//重写sexStr的get方法
- (NSString *)sexStr{
    if (self.sex == 0){
        return @"男";
    }else {
        return @"女";
    }
}
@end
  • 数组的处理主要在方法- (void)setValue:(id)value forKey:(NSString *)key中,就是将拿到的数组进行遍历,然后赋值到DogModel存入新数组返回;
  • 对于Bool类型的处理,在获得数据是0是自动为NO,非0即为YES;
  • 对于后台给的type根据数值判断的我们可以在Model里进行处理,这里sex 0-男 1-女,自己定义了一个属性sexStr,根据需要对sex进行了转化,如果在哪里需要显示男女的话可以直接通过sexStr获得,减少了业务代码里面的数据处理。
  • 实现结果
带数组类型Model处理

最后附上demo地址:MCModelDemo

你可能感兴趣的:(iOS 利用KVC进行数据转模型)