ios学习8_KVC和字典转模型

原创 2015年07月07日 11:25:08

Key Value Coding是cocoa的一个标准组成部分,它能让我们可以通过name(key)的方式访问属性,某些情况下极大地简化了代码,可称之为cocoa的大招。

如下的例子:

使用KVC的好处

不使用KVC

- (id)tableView:(NSTableView *)tableview
objectValueForTableColumn:(id)column row:(NSInteger)row {
    ChildObject *child = [childrenArray objectAtIndex:row];
    if ([[column identifier] isEqualToString:@"name"]) {
       return [child name];
    }
   if ([[column identifier] isEqualToString:@"age"]) {
       return [child age];
    }
   if ([[column identifier] isEqualToString:@"favoriteColor"]) {   
       return [child favoriteColor];
    }
    // And so on. 
}

使用KVC

- (id)tableView:(NSTableView *)tableview
objectValueForTableColumn:(id)column row:(NSInteger)row {
    ChildObject *child = [childrenArray objectAtIndex:row];
    return [child valueForKey:[column identifier]];
}

显而易见,简化了很多代码。

KVC操作

KVC赋值

1 给当前对象属性赋值

- (void)setValue:(id)value forKey:(NSString *)key;

2给对象的属性的属性赋值

- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;

3 处理未定义的键

- (void) setValue:(id)value forUndefinedKey:(NSString *)key

4 字典转模型:会为我们把和dictionary的key名字相同的class proerty设置上dict中key对应的value

- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;

注意:要求字典中的key和对象属性一样,都是基本的OC数据类型:Array/Dictionary/Boolean/Data/Number/String

KVC取值

1 获取对象属性的值

- (id)valueForKey:(NSString *)key;

2 获取对象属性的属性的值

- (id)valueForKeyPath:(NSString *)keyPath;

例子:

Person * p = [[Person alloc]init];
Car *car = [[Car alloc]init];
p.car = car;
[p setValue:@"qhyuan" forKeyPath:@"name"];
[p setValue:@(20) forKey:@"id"];
[p setValue:@"baoshijie" forKeyPath:@"car.brand"];
[p setValue:@"180000" forKeyPath:@"car.price"];
NSLog(@"kvc賦值的person对象----%@",p);
NSString * name = [p valueForKey:@"name"];
NSString * brand = [p valueForKeyPath:@"car.brand"];
NSLog(@"%@ %@",name, brand);

字典转模型

常规情况


模型

Person.h

@interface Person : NSObject
@property (nonatomic, copy) NSString * name;
@property (nonatomic, assign) int age;
- (instancetype) initWithDict:(NSDictionary *) dict;
+ (instancetype) personWithDict:(NSDictionary *) dict;
+ (NSArray *) person;
@end
Person.m

@implementation Person
- (instancetype) initWithDict:(NSDictionary *) dict
{
    if(self = [self init])
{
// 使用KVC 字典转模型 如此方便,省去了大量的赋值代码
[self setValuesForKeysWithDictionary:dict];
    //self.name = dict[@"name"];
    //self.age = [dict[@"age"] integerValue];
    }
    return self;
}
+ (instancetype) personWithDict:(NSDictionary *) dict
{
    return [[self alloc]initWithDict:dict];
}
+ (NSArray *) person
{
    NSMutableArray * mutablePersons = [NSMutableArray array];
    NSString * path = [[NSBundle mainBundle] pathForResource:@"persons.plist" ofType:nil];
    NSArray *persons = [[NSArray alloc] initWithContentsOfFile:path];
    for (NSDictionary * person in persons) {
        [mutablePersons addObject:[self personWithDict:person]];
    }
    return mutablePersons;
}
- (NSString *) description
{
    NSString * desc = [NSString stringWithFormat:@"<%p:(%@,%d)>",self,self.name,self.age];
    return desc;
}
@end

字典中多个某些key是OC中的关键字


如果将键age换成了id

会抛出异常:

*** Terminating app due to uncaught exception 'NSUnknownKeyException',reason: '[<Person 0x8c419a0> setValue:forUndefinedKey:]: this class isnot key value coding-compliant for the key id.

重写以下方法即可,处理未定义的键

- (void)setValue:(id)value forUndefinedKey:(NSString *)key;

解决方式:

- (void) setValue:(id)value forUndefinedKey:(NSString *)key
{
    if([key isEqualToString:@"id"])
        key = @"age";
    [super setValue:value forKey:key];
}

字典里面还包含某些对应自定义类的字典或者数组


Person类增加了一个Car类型的属性

@property (nonatomic, strong) Car * car;

我们只需要重写以下方法

- (void)setValue:(id)value forKey:(NSString *)key;

解决方法:

- (void)setValue:(id)value forKey:(NSString *)key
{
    if([key isEqualToString:@"cars"])
    {
        Car *car = [Car carWithDict:(NSDictionary *)value];
        self.car = car;
    }
    else
        [super setValue:value forKey:key];
}
打印结果

字典转模型[5525:60b] (

    "<Person:(zhangsan,20,<Car:(benchi,180000)>)>",

   "<Person:(lisi,22,<Car:(baoma,180000)>)>",

   "<Person:(wangwu,24,<Car:(aodi,180000)>)>"

)

如果不只是增加了Cars属性而是增加了Cars数组,也是类似的方式。

runtime模型与字典互转

原文出自:标哥的技术博客 前言在开发中必不可少的模型与字典互转,但是一直以来都是使用他人的库,从来没有研究其原理或者说深究其所以然。现在,在这里我们一起来学习通过runtime完成模型与字典的互转。声...
  • woaifen3344
  • woaifen3344
  • 2015年12月29日 19:20
  • 2138

iOS中字典转模型的方法及底层原理

1 自动打印属性字符串分类 提供一个分类,专门根据字典生成对应的属性字符串。 @implementation NSObject (Property) + (void)PH_createPro...
  • intheair100
  • intheair100
  • 2017年06月07日 21:19
  • 804

iOS数据处理之字典转模型

当程序中有需要用到plist文件去存储一些东西的时候,我们在程序中也需要动态地去获取到plist文件中的内容并且使用它们。在MVC设计模式中,M指的是modal,代表着程序需要的数据,所以我们需要创建...
  • nineteen_
  • nineteen_
  • 2015年09月18日 20:41
  • 1693

Objective-C中ORM的运用:实体对象和字典的相互自动转换

iOS开发中基于ORM的框架很多,如SQLitePersistentObject,实际开发中需求不同或场景不同,方式方法也就不同,有时项目中用不上ORM框架,或者出于公司或项目组习惯或规范、实际项目需...
  • cooldragon
  • cooldragon
  • 2014年02月08日 20:32
  • 16640

关于 KVO 和 KVC 的一些总结 以及使用KVC进行字典和模型的互相转换

一直对KVO 和KVC都是停留在 只是知道的情况,从来没有尝试这在项目中使用,最近准备总结一下,在项目里面简单的使用一下 1、什么是KVO? KVO其实就是Key-Value-Observer,...
  • u011303663
  • u011303663
  • 2015年12月30日 17:58
  • 611

ios学习8_KVC和字典转模型

Key Value Coding是cocoa的一个标准组成部分,它能让我们可以通过name(key)的方式访问属性,某些情况下极大地简化了代码,可称之为cocoa的大招。 如下的例子: 使用KVC...
  • bjx18356163055
  • bjx18356163055
  • 2016年02月15日 19:41
  • 99

使用KVC进行字典转模型

在项目中我们一般的都会碰到Json字段请求回来进行模型封装的情况,一般我们是建立一个Model然后Model里面有Json请求回来的模型字典里的各种字段,类似 name,age…….之类的。封装的时候...
  • xiaocai159753
  • xiaocai159753
  • 2015年04月26日 19:37
  • 1647

MJExtension使用,数据跟模型之间的相互转换

MJExtension使用(转) 1. MJExtension使用指导(最新) 2. MJExtension[模型字典]包含[模型字典数组]解析数据的bug及处理方法 ...
  • m7723sun
  • m7723sun
  • 2016年09月13日 22:09
  • 2647

IOS 字典模型互转框架 MJExtension

MJExtension是一套字典和模型之间互相转换的超轻量级框架 MJExtension能完成的功能 字典(JSON) --> 模型(Model) 模型(Model) --> 字...
  • liuzhihui666
  • liuzhihui666
  • 2017年04月08日 17:01
  • 198

iOS模型设计---字典转模型

 iOS模型设计 在iOS开发中,模型一词几乎伴随着每个程序员的开发生涯。在接触模型之前,小编在开发中也会经常碰到逻辑混乱、条理不清晰等情况。接下来...
  • smallyou113
  • smallyou113
  • 2016年05月16日 10:03
  • 3606
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ios学习8_KVC和字典转模型
举报原因:
原因补充:

(最多只允许输入30个字)