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

转载于:https://www.cnblogs.com/qhyuan1992/p/5385300.html

ios学习8_KVC和字典转模型相关推荐

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

    一.能完成功能的"问题代码" 1.从plist中加载的数据 2.实现的代码 1 // 2 // LFViewController.m 3 // 03-应用管理 4 // 5 // ...

  2. iOS 用runtime封装字典转模型

    封装字典转模型: 只需传入model名和json数组,用runtime动态的为每个属性赋值,导入头文件objc/runtime,首先,记录model类中的成员变量数,然后class_copyprope ...

  3. IOS应用管理学习,进阶,涉及字典转模型,工厂方法,面向对象思想,页面布局等

    IOS应用管理学习,进阶,涉及字典转模型,工厂方法,面向对象思想,页面布局等 前言:人为规定的参数 每一个 小view视图 宽度 80 高度 90 数据类型 CGFloat 定义, 3 列,数据类型 ...

  4. iOS开发之如何将字典转为模型

    2019独角兽企业重金招聘Python工程师标准>>> 刚刚学习了如何读取plist,将plist中的字典对象转成数组对象.字典和模型都可以存储数据,既然都可以存储对象,那么为什么要 ...

  5. IOS之YYModel字典转模型第三方框架的使用

    IOS之YYModel字典转模型第三方框架的使用 字典转模型,可以使用原生的KVC方式,也可使用第三方框架,常见的有YYModel,MJExtension,JSONModel,FastEasyMapp ...

  6. iOS swift5 字典转模型(二)

    iOS (swift,oc)字典转模型(一)框架 YYModel HandyJSON Swift之Codable实战技巧 - 知乎

  7. IOS第四天-新浪微博 -存储优化OAuth授权账号信息,下拉刷新,字典转模型

    *************application - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOpti ...

  8. Runtime(字典转模型)学习

    Runtime字典转模型思路:通过Runtime获取模型中的属性(对应字典中的key),通过属性去字典中取出对应的value,然后给模型的属性赋值. Demo链接 // ViewController. ...

  9. 工业4.0 资产管理壳学习笔记( 5) 模型中的语义,概念和字典

    模型是真实事物的简单描述.一段描述模型的语言指向的哪一个真实事物.这就是这一段文字的语义(semantic).在计算机建模中,一个模型具有确定的语义十分重要. 我们知道,人类的自然语言中存在许多二义性 ...

最新文章

  1. qpython3安装kivy_kivy库的安装
  2. 网站内部优化的4个细节小技巧
  3. 2020(广东)功能性农业大健康大会中国农民丰收节交易会
  4. [USACO18JAN][luoguP4183 ]Cow at Large P
  5. Python 类的特殊成员方法详解
  6. 在jenkins上配置 sonar 两种方式的区别
  7. 匈牙利命名法为何被淘汰_为何甲烷的习惯命名法用甲烷而不是一烷?
  8. 全网首发:warning: #warning “Using deprecated NumPy API, disable it by “ “#defining NPY_NO_DEPRECATED_API
  9. 基于STM32的自由度云台运动姿态控制系统
  10. 微信的Linux版本,ubuntu16.04安装微信,linux原生版
  11. PHP学习之GD库图像处理
  12. django 名词解释
  13. XINS Web服务框架
  14. JavaScrpit+Html实现“网页播放视频“效果(应用场景:腾讯PC端视频播放器、以及各视频网站页面开发设计)
  15. 关于Win10创意者更新之后蓝屏的修复办法
  16. 关于阿里巴巴编码规范(Java)认证
  17. 03 循环、字符串、列表、元祖、字典
  18. GLUT之鼠标事件两点画线 4
  19. [HTML]入门小知识,列表?框架?表格?来吧。纯手工制作,满满都是智慧
  20. Redis基本命令大全

热门文章

  1. 数据结构:栈的了解与示例(逆波兰表达式)
  2. Python遍历破解FTP密码,并上传webshell
  3. SQLSERVER远程备份
  4. Python基础知识汇总
  5. Spring 系统学习:Spring的事务管理---事务回顾
  6. 基于Bootstrap的Asp.net Mvc 分页的实现(转)
  7. ueditor分布式部署
  8. 【WebSocket】手把手教会使用WebSocket
  9. ROS学习笔记4(编译一个ROS Package)
  10. python编译出来的程序员_Windows下编译Python2.7源码