文档章节

iOS--KVC

gitzhengjianhua
 gitzhengjianhua
发布于 2016/07/22 17:27
字数 1309
阅读 31
收藏 1

一直在使用一些方法比如在给模型赋值时使用的setValuesForKeysWithDictionary:jsonObject、改变一些属性时valueForKeyPath等。但面试的时候,面试官一句给我说一个应用场景。我靠,当时我想吃土。结果是当然回答的不好,当然我会使用KVC,我也知道它,但我不能驾驭KVC。

有个观点我很认同,我们做前端的只要会用知道怎么用怎么搭建出界面就行,这样我们的任务就完成。但是如果知道运行原理,我们能作出更好的App。就比如组装车的如果知道发动机和刹车运行机制,那么他就能组出性能更棒的车,也能避免好多问题。

a、介绍

我们可以用KVC直接使用字符串访问成员变量,而不使用setter或者getter方法。原因是KVC提供了一种在编译时动态访问对象属性和成员变量的方法。它很灵活但同时也失去了在编译期间的检查,如果有错我们也只能在运行时发现,比如通过使用valueForKeyPath访问一个属性或者其它时,只用当真正运行此处的时候我们才能发现是否有此属性。

b、注意点

  1. valueForKey:以字符串调用对象的get属性方法,或者读取成员变量的值;setValue:forKey:以字符串调用对象的set属性方法,或者修改成员变量的值。
  2. 对于基本数据类型,KVC方法会对基本数据类型进行封装(基本数据类型封装为NSNumber,其他结构体类型封装为NSValue)。比如int型,valueForKey:方法返回的是NSNumber对象,需要再调用intValue取出其中的值。setValue:forKey:方法与之类似,接收NSNumber参数。
  3. 在使用KVC时,如果找不到字符串对应的属性和成员变量时会怎么样?此时会调用valueForUndefinedKey:或者setValue:forUndefinedKey:这两个方法,默认情况下会抛出异常。一般我自己在模型对象中会重写这两个方法,因为当模型对象中的属性名称和后台返回的json里面某些数据名称不一样时,可以很方便的检测出,也能防止崩溃。
  4. 默认情况下KVC方法能够直接访问类的私有成员变量(就上面那个面试,我在苦思冥想之后说KVC可以访问到私有变量,但是面试官一句那要私有干嘛。呃  我当时想,完了  没法玩了  完全不在一个等级上),也可以重写accessInstanceVariablesDirectly方法,并令其返回NO(默认是返回YES)。KVC方法定义在NSKeyValueCoding类别中,该类别附加于NSObject类上,所以所有对象都具有这些方法。在此,反正我不提倡访问私有变量,就如哪位面试官说的。声明私有代表不想被访问到,我们如果这样干不是逆天而行吗?如果真的在外部使用到此变量,它还是私有的,大多数情况下只能说明我们自己的设计有问题,当然也有例外。
  5. 在一些特殊的类的对象上调用KVC方法会有特别的效果。对于数组NSArray、集合NSSet,调用valueForKey:会对每个数组和集合成员调用valueForKey:,并返回新的数组或者集合。如我们需要把一个数组里面的字符串取出来将首字母大写,并将新的字符串存到新数组中我们可以使用KVC很方便的达到需求

      [array valueForKeyPath:@“str.capitalizedString”];

valueForKeyPath称为键值链(Key Path)。键值链是用点将若干键相连的字符串,通过在对象上调用valueForKeyPath:或者setValue:forKeyPath:。

c、干货

KVC有些东西经常被忽略掉,但是很使用的小技巧。

我对于KVC嵌套知识点学习自一篇简书,感觉人家整理的很棒,先感谢人家,在此就厚颜无耻的引用下。

文/水瓶座_iOSer(简书作者)

原文链接:http://www.jianshu.com/p/a6a0abac1c4a

获取数组里的,最大、最小、平均、求和

NSArray *array = @[@"10",@"35",@72,@78,@"1"]; 

NSNumber *sum = [array valueForKeyPath:@"@sum.floatValue"]; 

NSNumber *avg = [array valueForKeyPath:@"@avg.floatValue"]; 

NSNumber *max = [array valueForKeyPath:@"@max.floatValue"]; 

NSNumber *min = [array valueForKeyPath:@"@min.floatValue"];  

删除重复数据

NSArray *array = @[@"name", @"w", @"aa", @"zxp", @"aa"]; //返回的是一个新的数组

 NSArray *newArray = [array valueForKeyPath:@"@distinctUnionOfObjects.self"]; 

NSLog(@"%@", newArray);

同样可以嵌套使用,先剔除name对应值的重复数据再取值

NSArray *array = @[ @{@"title":@"zxp",@"name":@"zhangxiaoping"}, @{@"title":@"zxp2",@"name":@"zhangxiaoping2"}, @{@"title":@"zxp",@"name":@"zhangxiaoping3"}, @{@"title":@"zxp",@"name":@"zhangxiaoping"}];

//根据name字段,来进行重复删除。

NSArray *newArray = [array valueForKeyPath:@"@distinctUnionOfObjects.name"];

//如果要根据title字段来删除重名的写法为`@distinctUnionOfObjects.title` 

NSLog(@"%@", newArray);

/*

print:( zhangxiaoping3, zhangxiaoping2, zhangxiaoping)是一个字符串数组*/

进行实例方法的调用

NSArray *array = @[@"name", @"w", @"aa", @"ZXPing"]; 

NSLog(@"%@", [array valueForKeyPath:@"uppercaseString"]);

相当于数组中的每个成员执行了uppercaseString方法,然后把返回的对象组成一个新数组返回。既然可以用uppercaseString方法,那么NSString的其他方法也可以,比如[array valueForKeyPath:@“length"]。当然,其他对象的实例方法也可以以此类推来进行调用。

© 著作权归作者所有

共有 人打赏支持
gitzhengjianhua

gitzhengjianhua

粉丝 4
博文 25
码字总数 23833
作品 3
渭南
Knowledge-Reserve

Knowledge-Reserve ComputerOperatingSystem 编译 静态库&动态库(Linux) 静态链接&动态链接 内存 内联函数&宏 Static&Const 死锁 线程安全 线程同步 锁 DataStructure Programme 集约型&离散...

旭宝爱吃鱼
08/16
0
0
[北京望京][15K-20K] 掘金招聘 iOS 开发

号外!号外!iOS 工程师又有人要啦! 望京 SOHO,望京 SOHO,iOS 工程师招聘了 你你你不来不来参加参加,你快投快投简历啊 不用犹豫了,我们等的就是你! ̋(ˊᵒ̴̶̷̤ ꇴ ᵒ̴̶̷̤ˋ)...

稀土君
07/11
0
0
iOS高仿QQ侧滑控件、下载框架、动画效果、扫一扫、颜色变化、K线图等源码

iOS精选源码 仿京东"加入购物车"转场动画(http://www.code4app.com/thread-28162-1-1.html) ColorTool(颜色转换)(http://www.code4app.com/thread-29256-1-1.html) Swift 专业版K线(http://w......

sunnyaigd
04/17
0
0
iOS开发·runtime+KVC实现多层字典模型转换(多层数据:模型嵌套模型,模型嵌套数组,数组嵌套模型)

本文实验Demo传送门:DictToModelDemo 前言:将后台JSON数据中的字典转成本地的模型,我们一般选用部分优秀的第三方框架,如SBJSON、JSONKit、MJExtension、YYModel等。但是,一些简单的数据...

陈满iOS
05/08
0
0
iOS与JS交互之UIWebView-协议拦截

级别:★★☆☆☆ 标签:「iOS与JS交互」「UIWebView与JS交互」「UIWebView拦截协议」 作者: Xs·H 审校: QiShare团队 先解释下标题:“iOS与JS交互”。iOS指原生代码(文章只有示例),J...

QiShare
08/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

打开eclipse出现an error has occurred see the log file

解决方法: 1,打开eclipse安装目录下的eclipse.ini文件; 2,打开的文本文件最后添加一行 --add-modules=ALL-SYSTEM 3,保存重新打开Eclipse。...

任梁荣
昨天
3
0
搞定Northwind示例数据库,无论哪个版本的SQLServer都受用

Northwind数据库 从这里可以找到突破口: http://social.msdn.microsoft.com/Forums/zh-CN/Vsexpressvb/thread/8490a1c6-9018-40c9-aafb-df9f79d29cde 下面是MSDN: http://msdn2.microsoft......

QQZZFT
昨天
1
0
mysql主从同步,安装配置操作

准备 两台mysql服务,我这里准备了如下: 主库:192.168.176.128 从库:192.168.176.131 如何在Linux上安装mysql服务,请看https://blog.csdn.net/qq_18860653/article/details/80250499 操作...

小致dad
昨天
3
0
一个手机装天下,走遍中国都不怕!

导读 “1200元(人民币,下同),微信支付,可以,你扫我。”来自西非马里共和国的展商Albert拿着手机,和一位买走他手鼓的中国游客用简单的汉语交流着。 近日,“第十四届中俄蒙经贸洽谈暨商品...

问题终结者
昨天
2
0
Redis的“死键”问题

大规模的数据库存储系统中,数据的生命周期管理是很有必要的;从业务角度发现过期数据,数据归档和数据碎片整理等。以MySQL为例,1个运行很久的TB级MySQL实例中,极有可能数百GB的数据,对业...

IT--小哥
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部