IOS 高级开发 KVC(二)
前一篇博客最后介绍了KVC 再json 转模型时遇到一些问题。今天接着来介绍KVC 的其他用法。其实我们在一开始的时候就一直再强调命名的重要性。命名规范是KVC 存活的基础。如果没有这个条件支撑,那么KVC使用起来就不会那么简单了。在这里大王再哔哔几句,作为一个程序员,不管我们长得有多丑,我们的代码一定好看。一段规范的代码代表我们的脸面,也是程序员成熟的标志。既然说到了命名,那么就再来看看KVC 让人吃惊的一面。
1)KVC 方法的搜索顺序
当你看到这个标题的时候,可能会诧异,说的是啥啊?啥是搜索顺序啊?别着急,在介绍调用顺序之前,我们先来看一段很简单的代码,先热身一下。假设我们有一个Person类,这个类是个宅男,头文件中啥玩意都没有。既然头文件中没有任何属性,我们就直接看实现文件。
#import "Person.h" @interface Person () @property(nonatomic,copy)NSString* yourHand; @end @implementation Person -(instancetype)init
{
self=[super init];
if (self)
{
self.yourHand=@"你的右手";
}
return self;
} -(NSString*)girlFriend
{
NSLog(@"%s",__func__);
return self.yourHand;
} @end
为了防止宅男太过孤单,作为上帝的我,给他创建了手,并在一出生(init)时就给它赋值了。并且创建了一个girlFriend方法。如果我们想调用这个方法直接
[person girlFriend]是不行的(但是我们可以[person performSleector:@selector(girlFriend)],这是因为runtime的关系,这里不详细介绍,可以参看我前几篇博客),在这里,我们还可以这样调用
- (void)viewDidLoad
{
[super viewDidLoad]; Person *person=[[Person alloc] init]; NSLog(@"%@",[person valueForKey:@"girlFriend"]);
}
2015-04-27 20:56:37.207 KVC[19591:953199] -[Person girlFriend]
2015-04-27 20:56:37.207 KVC[19591:953199] 你的右手
了解了上面的内容,我们就可以来说说KVC与容器类。什么是容器类呢?说简单点就是数组和集合。这里没啥可说的,还是先看代码吧。还是这个Person类,我们先来稍微改动一下。头文件还是什么都没有,实现文件变为如下
#import "Person.h" @implementation Person -(NSUInteger)countOfFingers
{
return ;
} -(id)objectInFingersAtIndex:(NSUInteger)index
{
NSLog(@"这是第%lu个手指",index);
return @(index);
} @end
光看这段代码不神奇,再看一下测试方法和打印信息,我们就会感到很吃惊。
- (void)viewDidLoad
{
[super viewDidLoad]; Person *person=[[Person alloc] init]; NSLog(@"%@",[person valueForKey:@"fingers"]);
}
2015-04-27 21:10:53.990 KVC[19658:958083] 这是第0个手指
2015-04-27 21:10:53.991 KVC[19658:958083] 这是第1个手指
2015-04-27 21:10:53.991 KVC[19658:958083] 这是第2个手指
2015-04-27 21:10:53.991 KVC[19658:958083] 这是第3个手指
2015-04-27 21:10:53.991 KVC[19658:958083] 这是第4个手指
2015-04-27 21:10:53.991 KVC[19658:958083] 这是第5个手指
2015-04-27 21:10:53.991 KVC[19658:958083] 这是第6个手指
2015-04-27 21:10:53.992 KVC[19658:958083] 这是第7个手指
2015-04-27 21:10:53.992 KVC[19658:958083] 这是第8个手指
2015-04-27 21:10:53.992 KVC[19658:958083] 这是第9个手指
2015-04-27 21:10:53.992 KVC[19658:958083] (
0,
1,
2,
3,
4,
5,
6,
7,
8,
9
)
全过程我们都没有直接调用countOfFingers 和-(id)objectInFingersAtIndex:(NSUInteger)index 方法。由打印信息可以知道是系统帮我们调用了。并且有打印信息我们可以知道,系统把fingers 当成属性,并且这个“属性”是数组类型的。当我们调用valueForKey:时,系统会按如下顺序调用方法
如果都找不到的话,系统会调用valueForUndefinedKey:方法。以上所讲的都是针对不可变的容器类。如果是可变的容器类,我们可以可以这样使用
dataM= [data mutbaleArrayValueForKey:@"属性"]。当dataM改变的时候,会向data发送消息,data中的内容也会跟着改变。这里我就不详细演示了,有兴趣的可以自己试一下。
2)高阶消息传递
大家可能冷不丁的看到高阶这个词感觉很高大上,仿佛又回到了大学的高数课堂。那么什么是高阶消息传递呢?说白了就是让数组中的每一个元素都执行某个方法,并把结果返回到新的数组中。这下感觉不那么高大上了吧?下面来看一个经典的例子代码
- (void)viewDidLoad
{
[super viewDidLoad]; NSArray *array=@[@"烤串",@"啤酒",@"爆米花"];
NSArray *lengths=[array valueForKeyPath:@"capitalizedString.length"];
NSLog(@"%@",lengths);
}
2015-04-27 21:53:25.531 KVC[19821:972219] (
2,
2,
3
)
我们可以看出,数组中的每一项都执行了capitalizedString 方法,执行完后,又执行了length 方法。然后把结果返回到新的数组中。在开发中,我们可以适当的使用这个方法,会减少我们的代码量。
尽管KVC很高大上,但是我们现实开发中,还是谨慎地使用,因为它太过于强大,贸然使用可能会无意间破坏程序的封装性。所以我们只有想清楚了之后再使用,而且最好在使用的地方加上注释。KVC 是大招,我们要在必要的时候使用,动画片里孙悟空也不是在一开始就放大招,你说是不?
IOS 高级开发 KVC(二)的更多相关文章
- IOS 高级开发 KVC(一)
熟练使用KVC 可以再开发过程中可以给我们带来巨大的好处,尤其是在json 转模型的时候,KVC让程序员摆脱了繁琐无营养的代码堆积.减少代码量就是减少出错的概率.KVC 用起来很灵活,这种灵活的基础是 ...
- (转发)IOS高级开发~Runtime(二)
一些公用类: @interface ClassCustomClass :NSObject{ NSString *varTest1; NSString *varTest2; NSString *varT ...
- (转发)IOS高级开发~Runtime(四)
用C代替OC: #import <objc/runtime.h> #import <objc/message.h> #import <stdio.h> extern ...
- (转发)IOS高级开发~Runtime(三)
11.系统类的方法实现部分替换 - (void) methodExchange { Method m1 = class_getInstanceMethod([NSStringclass],@selec ...
- (转发)IOS高级开发~Runtime(一)
IOS高级开发-Runtime(一) IOS高级开发-Runtime(二) IOS高级开发-Runtime(三) IOS高级开发-Runtime(四) 一些公用类: @interface Custom ...
- iOS蓝牙开发(二)蓝牙相关基础知识
原文链接: http://liuyanwei.jumppo.com/2015/07/17/ios-BLE-1.html iOS蓝牙开发(一)蓝牙相关基础知识: 蓝牙常见名称和缩写 MFI ====== ...
- IOS高级开发之多线程(四)NSOperation
1.什么是NSOperation,NSOperationQueue? NSOperation是一个抽象的基类,表示一个独立的计算单元,可以为子类提供有用且线程安全的建立状态,优先级,依赖和取消等操作. ...
- IOS 高级开发 runtime(二)
二.移魂大法 使用runtime还可以交换两个函数.先贴上代码和执行结果. #import <Foundation/Foundation.h> @interface DZLPerson : ...
- ios高级开发之多线程(二)NSThread技术
多线程技术是有多套解决方案的,那么我们该如何选择呢? 技术方案 简介 语言 线程生命周期 使用频率 pthread 1.一套通用的多线程API 2.适用于UNIX,linux,windows等 3.跨 ...
随机推荐
- 转载 ASP.NET常用的正则表达式
转载原地址: http://www.cnblogs.com/0001/archive/2010/01/26/1656677.html 常用表达式: "^\d+$" //非负整数(正 ...
- OpenCV入门学习笔记
OpenCV入门学习笔记 参照OpenCV中文论坛相关文档(http://www.opencv.org.cn/) 一.简介 OpenCV(Open Source Computer Vision),开源 ...
- Outlook账户迁移帮助
Outlook账户迁移指南 1. 介绍 开贴聊聊如何迁移Outlook用户账户到另外一台电脑. 相信许多Outlook用户都遇到过这样的情况:买来一台新电脑,安装完Outlook后,想把旧电脑里面的O ...
- Float(浮动)
一.什么是浮动? CSS 的 Float(浮动),会使元素向左或向右移动,其周围的元素也会重新排列. 二.浮动元素的特点 元素浮动后会自动变成行块元素 浮动元素的父元素高度宽计算将忽略浮动子元素 浮动 ...
- 在Entity Framework中重用现有的数据库连接字符串
本文转载:http://www.cnblogs.com/dudu/archive/2011/01/29/entity_framework_connection_string.html 如果EF在使用实 ...
- 关于 mysql.test 数据库
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- Samba Linux和Windows互访
之前一直用的sshfs manager,但是会出现造成电脑黑屏的情况.网上也没找到其它类似的软件. 后面打算用Samba 直接搜到一篇很强大的文章. 1. 下载及安装Samba 推荐用yum来安装, ...
- materialish-progress
https://github.com/pnikosis/materialish-progress materialish-progress-master.zip
- document.location的属性
示例html完整路径为: http://10.10.3.117:8500/html/ypt/index.html alert("document.location.href:"+d ...
- 关于 ioctl 的 FIONREAD 參数
ioctl 是用来设置硬件控制寄存器,或者读取硬件状态寄存器的数值之类的.而read,write 是把数据丢入缓冲区,硬件的驱动从缓冲区读取数据一个个发送或者把接收的数据送入缓冲区. ioctl(ke ...