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

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

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

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

  1. iOS开发UI篇—字典转模型

    iOS开发UI篇—字典转模型 一.能完成功能的“问题代码” 1.从plist中加载的数据 2.实现的代码 // // LFViewController.m // 03-应用管理 // // Creat ...

  2. iOS 懒加载 字典转模型

    >>>懒加载 一.介绍 懒加载又称延时加载,即在系统调用时加载,如果系统不调用则不会加载,所谓懒加载其实就是重写其get方法. 在使用懒加载时要先判断该方法是否存在,如果不存在再进行 ...

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

    Mantle简介 Mantle 是iOS和Mac平台下基于Objective-C编写的一个简单高效的模型层框架. Mantle能做什么 Mantle可以轻松把JSON数据.字典(Dictionary) ...

  4. iOS开发—字典转模型,KVC设计模式

    iOS开发UI基础—字典转模型 开发中,通常使用第三方框架可以很快的实现通过字典转模型,通过plist创建模型,将字典的键值对转成模型属性,将模型转成字典,通过模型数组来创建一个字典数组,通过字典数组 ...

  5. iOS学习笔记38-MJExtension使用

    一.MJExtension第三方框架 我们在iOS开发过程中,我们常常需要将字典数据(也就是JSON数据)与Model模型之间的转化,例如网络请求返回的微博数据.等等,如果我们自己全部手动去创建模型并 ...

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

    一:KVC和KVO的学习 #import "StatusItem.h" /* 1:总结:KVC赋值:1:setValuesForKeysWithDictionary实现原理:遍历字 ...

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

    一:url转码,当url中涉及到中文的时候,要考虑转码,用UTF8对中文的url进行转码 #import "ViewController.h" @interface ViewCon ...

  8. iOS开发——高级技术精选OC篇&Runtime之字典转模型实战

    Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://w ...

  9. iOS开发——网络篇——JSON和XML,NSJSONSerialization ,NSXMLParser(XML解析器),NSXMLParserDelegate,MJExtension (字典转模型),GDataXML(三方框架解析XML)

    一.JSON 1.JSON简介什么是JSONJSON是一种轻量级的数据格式,一般用于数据交互服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) JSON的格式很像OC中的字典 ...

随机推荐

  1. 软件开发:速度 vs 质量

    程序开发项目进行过程中,通常会冒出这样的困惑:应该选择速度,还是选择质量?很多程序猿都会有偷懒的思维,觉得把一些摸不清头绪.不知道怎么写的代码片段去掉,可以节省很多时间,更早完成项目计划. 其实过去几 ...

  2. react.js工程结构

    1.index.html :UI界面入口.挂在点: 2.manifest.json:应用说明 3.package.json:工程说明.依赖说明等 4.source : 代码源文件

  3. hdfs的特性、命令、安全模式、基准测试

    1.第一点:如何理解hdfs分布式文件系统,每台机器出一块磁盘,凑成一个大的硬盘,大的硬盘的容量来自各个服务器的硬盘容量之和. 你出5毛,我出5毛,大家凑成1块. 2. HDFS 是 Hadoop D ...

  4. DHCP和PXE

    继续学习,Let's go!DHCP和PXE都是什么呢?如果非科班出身,可能一脸懵逼,好多东西需要去学习了,真的,继续学吧,付出不一定会有回报,不付出肯定就是等死了,呵呵! 一.DHCP 真正需要手动 ...

  5. MRC转ARC(2)

    春节前抽空花了一天的时间将手头的工程从MRC转成了ARC,然后陆陆续续地修复一部分因为转ARC引起的内存泄漏和崩溃,到目前为止工程也算是比较稳定了,抽空记上一笔.(虽说这种事情这辈子估计都只会做这么一 ...

  6. 诊断:RHEL7安装11.2RAC时root.sh错误ohasd failed to start

    RHEL 7.5中安装11gRAC时,在grid infrastructure的root.sh执行时,报错: # /oracle/product/11g/grid/root.sh ... Adding ...

  7. Django 模版语法 二

    变量的过滤器(filter)的使用 过滤器:upper, lower, first, capfirst 在 views.py 中修改 from django.shortcuts import rend ...

  8. time | sys | os 模块,递归删除文件,项目分析

    一,复习 ''' 1.跨文件夹导包 - 不用考虑包的情况下直接导入文件夹(包)下的具体模块 2.__name__: py自执行 '__main__' | py被导入执行 '模块名' 3.包:一系列模块 ...

  9. 集训第六周 E题

    E - 期望(经典问题) Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit S ...

  10. HDU-5583-Kingdom of Black and White(2015ACM/ICPC亚洲区上海站-重现赛)

    Kingdom of Black and White                                                                           ...