原创Blog,转载请注明出处
blog.csdn.net/hello_hwc


前言:本文的架构
KVC的定义
KVC的几个场景

希望,通过本文让不了解KVC的同学入门,KVC在IOS开发中是个比较重要的概念,也是理解KVO的基础。


一 KVC的定义
KVC的全称是key-value coding,通过key-value的方式来访问属性。在很多地方,KVC是非常方便的。
属性

@property (strong,nonatomic) NSString * message;

赋值

 [self setValue:@"blog.csdn.net/hello_hwc" forKey:@"message"];

取值

 NSString * message =   [self valueForKey:@"message"];

除了对象可以用KVC,对标量也可以用KVC,因为Foundation对标量的KVC进行了内部转换。
例如

@property (nonatomic) int number;
[self setValue:@(10) forKey:@"number"];
NSNumber *  num = [self valueForKey:@"number"];

以上讲的都是valueForKey,KVC也支持valueForKeyPath,这里的path是字符串路径,用点来隔开,逐层深入。
例如

所以,valueForKeyPath对于复杂的集合类处理以及对于复杂的属性访问很简便。
例如

    NSArray * array = @[@{@"key":@{@"1":@"2"},@"key2":@"value2"},@{@"key":@{@"1":@"3"},@"key2":@"value2"},@{@"key":@{@"1":@"4"},@"key2":@"value2"}];NSLog(@"%@",[array valueForKeyPath:@"key.1"]);

简单讲解下这个过程
对每个对象进行valueForKey:@”key”,然后对返回的数组在进行
valueForKey@“1“


二 KVC的典型使用场景

2.1 Model与View同步的中间件。
我写了个简单的使用Demo
效果如图

每次点Create,会生成100以内随机数,然后几个label分别展示相应的统计。

这里的核心是model和view的同步。

采用如下代码来实现

-(NSArray *)stringKeys{return @[@"min",@"max",@"avg"];
}-(NSString *)aggregationKeypath:(NSString *)key{return [NSString stringWithFormat:@"@%@.self",key];
}-(UILabel *)labelForKey:(NSString *)key{return [self valueForKey:key];
}-(void)updateAggregationLabels{ for (NSString * key in self.stringKeys) {UILabel * label = [self labelForKey:key];NSNumber * aggregation = [self.numArray valueForKeyPath:[self aggregationKeypath:key]];label.text = [NSString stringWithFormat:@"%@: %.1f",key,aggregation.doubleValue];}
}- (IBAction)createTenRandomNumbers:(id)sender {[self.numArray removeAllObjects];NSString * string = @"";for (int i = 0; i < 10; i++) {int num = arc4random()%100;[self.numArray addObject:@(num)];string = [NSString stringWithFormat:@"%@ %d",string,num];}self.numbers.text = string;[self updateAggregationLabels];
}

这里,用KVC的方式访问属性。

有些同学不禁会问,我干嘛不直接在这个target-action中直接响应。这么写主要是为了方便以后维护。例如,假如我要新加上一个label叫做count,以上的代码中,我只需要修改一个函数,就是为
-(NSArray *)stringKeys{return @[@"min",@"max",@"avg"];
}
这个数组添加一个新的key。一个简单的例子,抛砖引玉,主要是尽量解耦合的思想,这个很重要。

2.2 KVC集成了几个集合的运算符,用起来非常方便,代码执行效率也很高。
集合运算符的表达形式就是在keyPath中的双引号里面出现@
例如

@"@min.count"

2.2.1集合运算符分为几种:

  • 简单集合运算符:返回string,number,date
  • 对象运算符:返回一个数组
  • 数组和集合运算符:返回一个数组或者集合

基本集合运算符分为几种

@count
@max
@min
@avg
@sum

为了更好的讲解,写一个model类

@interface User : NSObject
@property (strong,nonatomic)NSString * name;
@property (nonatomic) NSUInteger accessTimes;
-(instancetype)initWithName:(NSString *)name Count:(NSUInteger) times;
@end

然后,进行举例
对一个user的数组进行初始化

-(NSMutableArray *)users{if (!(_users)) {_users = [[NSMutableArray alloc] init];[_users addObject:[[User alloc] initWithName:@"jack" Count:100]];[_users addObject:[[User alloc] initWithName:@"lucy" Count:150]];[_users addObject:[[User alloc] initWithName:@"tom" Count:80]];[_users addObject:[[User alloc] initWithName:@"lily" Count:80]];}return _users;
}

然后,用KVC的形式进行访问数据

NSArray * names = [self.users valueForKeyPath:@"name"];NSArray * counts = [self.users valueForKeyPath:@"accessTimes"];NSNumber * avg = [self.users valueForKeyPath:@"@avg.accessTimes"];

2.2.2 对象操作符

@unionOfObjects     返回keyPath的结果,重复信息不过滤
@distinucUnionOfObjects  重复信息过滤

例如

 NSArray * time1 = [self.users valueForKeyPath:@"@unionOfObjects.accessTimes"];NSArray * time2 = [self.users valueForKeyPath:@"@distinctUnionOfObjects.accessTimes"];NSLog(@"%@",time1.description);NSLog(@"%@",time2.description);

输出

2015-02-12 21:12:38.513 KvcKvoDemo[501:11415] (
100,
150,
80,
80
)
2015-02-12 21:12:38.514 KvcKvoDemo[501:11415] (
150,
80,
100
)


2.3 KVC的一些错误处理
标量不能为nil
例如

@property (nonatomic) int number;

然后

[self setValue:nil forKey:@"number"];

如果不进行错误处理,程序就会崩溃

用这个函数进行想要的错误处理
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{NSLog(@"undfined key");
}

未识别的key处理

 [self setValue:nil forKey:@"dsag"];[self valueForKey:@"123124"];

胡乱输入的两个key,如果不进行错误处理,程序就会崩溃掉。
用这两个函数来处理未识别的key,至于怎么处理,因情况而定。

-(void)setValue:(id)value forUndefinedKey:(NSString *)key{NSLog(@"set undfined key");
}
-(id)valueForUndefinedKey:(NSString *)key{NSLog(@"get undfined key");return nil;
}

当然,用消息转发技术,在错误处理的下一步来处理错误也行。这其中又涉及到IOS runtime的内容,牵涉过多,不在本文的讨论范畴了。不过,不要让错误传递太久,及时处理掉,总没错。


IOS SDK详解之KVC相关推荐

  1. IOS SDK详解之拍照/相册(默认+自定义拍照界面)

    原创blog,转载请注明出处 blog.csdn.net/hello_hwc 前言: 本来要更新NSURLSession的UploadTask的,结果写那个Demo的时候想要写成拍照上传,然后就想到先 ...

  2. iOS SDK详解之视频播放(AVPlayer)附Demo

    原创Blog,转载请注明出处 http://blog.csdn.net/hello_hwc?viewmode=list 我的stackoverflow 前言 最近在研究视频播放,所以研究了下这个类,学 ...

  3. Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送

    Android高效率编码-第三方SDK详解系列(三)--JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送 很久没有更新第三方SDK这个系列了,所以更新一下这几天工作中使用到的推送, ...

  4. FreeEIM 来点新知识iOS UIScrollView详解

     老程序员FreeEIM 来点新知识iOS UIScrollView详解 UIScrollView 顾名思义也知道这个是和滚动相关的控件,在Android开发时遇到过ScrollView,当内容的 ...

  5. 腾讯小程序 java编写_微信小程序 使用腾讯地图SDK详解及实现步骤

    微信小程序 使用腾讯地图SDK详解及实现步骤 近期在做一款彩票服务类项目中用到了腾讯地图提供的小程序解决方案,拿来给大家分享一下! 使用起来非常简单,就是一些功能还有待完善. 官方文档:http:// ...

  6. Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!...

    Android高效率编码-第三方SDK详解系列(一)--百度地图,绘制,覆盖物,导航,定位,细腻分解! 这是一个系列,但是我也不确定具体会更新多少期,最近很忙,主要还是效率的问题,所以一些有效的东西还 ...

  7. iOS绘图详解-多种绘图方式、裁剪、滤镜、移动、CTM

    iOS绘图详解 摘要: Core Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎.它提供了低级别.轻量级.高保真度的2D渲染.该框架可以用于基于路径的 绘 ...

  8. IOS UIView详解

    文章目录 IOS UIView详解 1.官方类分析 2. UIView 常用的属性 2.1 UIView的圆角加阴影效果的实现 2.2 UIView 属性 2.2.1 UIView 几何属性 2.2. ...

  9. Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能

    Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 我的本意是第二篇写Mob的shareSD ...

最新文章

  1. 【深度学习理论】(2) 卷积神经网络
  2. 比特币现金锚定货币交易所越来越多
  3. acm寒假特辑1月24日 HDU - 2191(背包)/CodeForces - 500A
  4. socket编程之addrinfo结构体与getaddrinfo函数
  5. Docker启动失败 提示An error occurred和乱码
  6. FGPA异步信号问题
  7. mysql入门操作_对MySQL的几个入门操作
  8. MySQL 避坑指南之隐式数据类型转换
  9. 动画学信奥 漫画学算法 CSP-J入门级 (二)、C++程序设计 数据结构(依据「NOI大纲」)
  10. 用什么软件可以检测苹果耳机芯片_精确空间感知的超宽频U1芯片,或许才是新iPhone的秘密武器...
  11. $Django 聚合函数、分组查询、F,Q查询、orm字段以及参数
  12. python进阶08并发之四map, apply, map_async, apply_async差异
  13. 将json转为map的两种方式及前后端开发json Api设计规范总结
  14. vueh5调用摄像头拍照_Vue2.0实现调用摄像头进行拍照功能 exif.js实现图片上传功能...
  15. html2canvas关于图片不能正常截取 1
  16. linux 更换 镜像源
  17. html5 excel网页版,一种网页版EXCEL的实现方法与流程
  18. wo-mic ,audioRelay设置
  19. 在线作图|2分钟做Lefse分析
  20. 【Practical】并行化:VLIW

热门文章

  1. Vue中v-bind=“$attrs”的使用方法
  2. sklearn中lstm_利用LSTM网络进行预测,使用,做,预报,Forecast
  3. Nginx 解决跨域问题
  4. 索尼电视显示由于服务器无法启动,索尼电视无法安装软件怎么办,最新解决办法...
  5. 环保数采仪农村土壤监测应用
  6. 安卓重签名脚本——AndroidResigner.bat
  7. mapxtreme java学习之路(1)——.dwg转.tab再转.gst详细教程
  8. WASM VS EVM,波卡的选择预示了公链未来
  9. Tailwind Toggle
  10. 举例说明层次分析的三大原则_LabVIEW面向对象编程_初窥门槛(2)_设计原则(SOLID)...