ios学习8_KVC和字典转模型

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中的keyword

假设将键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数组,也是类似的方式。

时间: 2024-10-13 10:40:58

ios学习8_KVC和字典转模型的相关文章

iOS开发UI篇—字典转模型

iOS开发UI篇—字典转模型 一.能完成功能的“问题代码” 1.从plist中加载的数据 2.实现的代码 // // LFViewController.m // 03-应用管理 // // Created by apple on 14-5-22. // Copyright (c) 2014年 heima. All rights reserved. // #import "LFViewController.h" @interface LFViewController () @proper

文顶顶 iOS开发UI篇—字典转模型

iOS开发UI篇—字典转模型 一.能完成功能的“问题代码” 1.从plist中加载的数据 2.实现的代码 1 // 2 // LFViewController.m 3 // 03-应用管理 4 // 5 // Created by apple on 14-5-22. 6 // Copyright (c) 2014年 heima. All rights reserved. 7 // 8 9 #import "LFViewController.h" 10 11 @interface LFV

iOS开发UI基础—字典转模型(部分内容转载他人)

iOS开发UI基础-字典转模型 开发中,通常使用第三方框架可以很快的实现通过字典转模型,通过plist创建模型,将字典的键值对转成模型属性,将模型转成字典,通过模型数组来创建一个字典数组,通过字典数组来创建一个模型数组等等. 一.能完成功能的"问题代码" 1.从plist中加载的数据 2.实现的代码 1 // 2 // LFViewController.m 3 // 03-应用管理 4 // 5 // Created by apple on 14-5-22. 6 // Copyrigh

字典转模型框架 Mantle的使用:国外程序员最常用的iOS模型

Mantle简介 Mantle 是iOS和Mac平台下基于Objective-C编写的一个简单高效的模型层框架. Mantle能做什么 Mantle可以轻松把JSON数据.字典(Dictionary)和模型(即Objective对象)之间的相互转换,支持自定义映射,并且内置实现了NSCoding和NSCoping,大大简化归档操作. 为什么要使用Mantle 传统的模型层方案遇到的问题 通常我们用Objective-C写的模型层遇到了什么问题? 我们可以用  Github API 来举例.现在假

iOS学习笔记38-MJExtension使用

一.MJExtension第三方框架 我们在iOS开发过程中,我们常常需要将字典数据(也就是JSON数据)与Model模型之间的转化,例如网络请求返回的微博数据.等等,如果我们自己全部手动去创建模型并赋值,都是一些毫无技术含量的代码,费时费力,而且还可能会赋值出错,让我们很头疼. MJExtension框架就是为了解决这个问题而设计得第三方开源库.这个开源库是之前传智博客的讲师李明杰老师写的,现在他自己出来做了,我iOS入门都是看李明杰老师的培训视频学习的,他讲得非常好,我非常喜欢他,他也算是我

IOS 开发学习笔记-基础 UI(10)九宫格布局,块动画,字典转模型,Xib使用

大概如下图示:九个应用图标的样子 功能分析 (1)以九宫格的形式展示应用信息 (2)点击下载按钮后,做出相应的操作 步骤分析 (1)加载应用信息 (2)根据应用的个数创建对应的view (3)监听下载按钮点击 思路整理 要在支持文件夹里,放入 plist 文件,且拖拽素材到 supporting files,注意勾选的项目的区别: 大多数情况,往项目中拖拽素材时,通常选择 Destination, Folders:选择第一项:创建组,这样 xcode 导航显式的是黄色文件夹,要知道,Xcode中

ios开发runtime学习五:KVC以及KVO,利用runtime实现字典转模型

一:KVC和KVO的学习 #import "StatusItem.h" /* 1:总结:KVC赋值:1:setValuesForKeysWithDictionary实现原理:遍历字典,得到所有的key,value值,再利用kvc, setVaue forkey来为value赋值 2: [item setValue:@"来自即刻笔记" forKey:@"source"],内部的底层实现, 1.首先去模型中查找有没有setSource,找到,直接调用

ios开发网络学习二:URL转码以及字典转模型框架MJExtension的使用

一:url转码,当url中涉及到中文的时候,要考虑转码,用UTF8对中文的url进行转码 #import "ViewController.h" @interface ViewController () @end @implementation ViewController #pragma mark ---------------------- #pragma mark Events -(void)touchesBegan:(NSSet<UITouch *> *)touche

iOS之KVC字典转模型的底层实现

KVC: Key Value Coding (键值编码) 在iOS开发中,KVC是我们经常要使用的技术.那么KVC有什么作用呢?简单列举一下下面几种: 取值和赋值(开发中基本不用) 获取对象私有变量的值.(经常使用,例如UIPageContorl分页, 设置圆点为图片) 改变对象私有变量的值(经常使用) 简单的字典转模型(偶尔使用) 模型转字典 批量取值 KVC字典转模型的底层实现 通常我们手动将字典转模型的话,会在模型中提供一个类方法接收一个字典,在这个方法中将字典转换成模型,再将转换好的模型