本文转载 李朴之先生博客 http://blog.csdn.net/pucker/article/details/7413280

Objective-C中的KVC与KVO是两种比较重要的技术,这里简要介绍一下这两者的使用方法。

一、KVC

《iOS程序开发方法与实践》中介绍了KVC(Key–Value Coding,键值编码)的基本内容。

简要来说,KVC提供了一种在运行时而非编译时动态访问对象属性与成员变量的方式,也就是说,我们可以用字符串的内容作为属性名称或者成员变量名称进行访问。这种特性有些类似于其他高级编程语言中的反射。

举个例子,例如我们创建了一个类ClassA,其中定义了3个属性p1、p2和p3,以及1个实例方法getValueByPropertyName:,代码如下:

  1. @interface ClassA : NSObject
  2. @property (nonatomic) int p1;
  3. @property (nonatomic) int p2;
  4. @property (nonatomic) int p3;
  5. - (int)getValueByPropertyName:(NSString*)pName;
  6. @end
  7. @implementation ClassA
  8. @synthesize p1 = _p1, p2 = _p2, p3 = _p3;
  9. ...
  10. - (int)getValueByPropertyName:(NSString*)pName
  11. {
  12. if([pName isEqualToString:@"p1"])
  13. {
  14. return self.p1;
  15. }
  16. else if([pName isEqualToString:@"p2"])
  17. {
  18. return self.p2;
  19. }
  20. else if([pName isEqualToString:@"p3"])
  21. {
  22. return self.p3;
  23. }
  24. return 0;
  25. }
  26. @end

方法getValueByPropertyName:用于通过字符串来访问对应的属性值。如果我们想要向ClassA添加几个属性,那么这个方法就还需要添加几个else if语句。而如果使用KVC就会方便许多,代码如下:

  1. - (int)getValueByPropertyName:(NSString*)pName
  2. {
  3. NSNumber* pNumber = [self valueForKey:pName];
  4. return [pNumber intValue];
  5. }

这里有几点需要注意,首先这里的valueForKey:方法用于以字符串调用对象的get属性方法,或者读取成员变量的值;与之相对的是setValue:forKey:,它用于以字符串调用对象的set属性方法,或者修改成员变量的值。第二点需要注意的是,对于基本数据类型,KVC方法会对基本数据类型进行封装(基本数据类型封装为NSNumber,其他结构体类型封装为NSValue)。这里的p1、p2、p3定义为int型,而valueForKey:方法返回的是NSNumber对象,需要再调用intValue取出其中的值。setValue:forKey:方法与之类似,接收NSNumber参数。第三,在使用KVC时,如果找不到字符串对应的属性和成员变量时会怎么样?此时会调用valueForUndefinedKey:或者setValue:forUndefinedKey:这两个方法,默认情况下会抛出异常。第四,默认情况下KVC方法能够直接访问类的私有成员变量,如果我们不想这样,可以重写accessInstanceVariablesDirectly方法,并令其返回NO(默认是返回YES)。KVC方法定义在NSKeyValueCoding类别中,该类别附加于NSObject类上,所以所有对象都具有这些方法。第五,在一些特殊的类的对象上调用KVC方法会有特别的效果。对于数组NSArray、集合NSSet,调用valueForKey:会对每个数组和集合成员调用valueForKey:,并返回新的数组或者集合。

在KVC中还有一种常用技术,称为键值链(Key Path)。键值链是用点将若干键相连的字符串,例如“manufacturer.product.name”。通过在对象上调用valueForKeyPath:或者setValue:forKeyPath:,我们就可以在一条语句中接连调用制定的属性。请看下面的例子:

  1. @interface Product : NSObject
  2. @property NSString* name;
  3. @end
  4. @implementation Product
  5. @synthesize name = _name;
  6. - (void)dealloc
  7. {
  8. self.name = nil;
  9. [super dealloc];
  10. }
  11. @end
  12. @interface Manufacturer : NSObject
  13. @property Product* product;
  14. @end
  15. @implementation Manufacturer
  16. @synthesize product = _product;
  17. -(void)dealloc
  18. {
  19. self.product = nil;
  20. [super dealloc];
  21. }
  22. @end
  23. int main(int argc, const char * argv[])
  24. {
  25. @autoreleasepool
  26. {
  27. Manufacturer* apple = [[[Manufacturer alloc] init] autorelease];
  28. Product* iPhone4S = [[[Product alloc] init] autorelease];
  29. iPhone4S.name = @"iPhone 4S";
  30. apple.product = iPhone4S;
  31. Manufacturer* micro$oft = [[[Manufacturer alloc] init] autorelease];
  32. Product* win8 = [[[Product alloc] init] autorelease];
  33. win8.name = @"Windows 8";
  34. micro$oft.product = win8;
  35. NSArray* manufacturerArray = [NSArray arrayWithObjects:apple, micro$oft, nil];
  36. NSArray* productNameArray = [manufacturerArray valueForKeyPath:@"product.name"];
  37. NSLog(@"productNameArray:\n%@", productNameArray);
  38. }
  39. return 0;
  40. }

首先程序定义了两个类Product与Manufacturer,分别定义商品与制造商。Manufacturer类定义了一个product属性,Product类定义了name属性。在main函数中,我们创建了两个制造商苹果和微软,以及两个商品iPhone4S和Win8,并设置好他们之间的关系。然后程序将两个制造商放入数组中,在数组上调用valueForKeyPath:方法并传入键值链@"product.name"。于是数组首先执行valueForKey:@"product",它会在每个数组成员上调用product属性,获取每个制造商的商品,然后再在每个商品上调用valueForKey:@"name",获取每个制造商的每个商品的名称,并将结果放到另一个数组中。上述程序的输出结果为:

  1. productNameArray:
  2. (
  3. "iPhone 4S",
  4. "Windows 8"
  5. )

使用KVC的好处是非常灵活,但同时也丢失了编译时检查。

Objective-C中的KVC与KVO(上)的更多相关文章

  1. iOS中关于KVC与KVO知识点

    iOS中关于KVC与KVO知识点 iOS中关于KVC与KVO知识点  一.简介 KVC/KVO是观察者模式的一种实现,在Cocoa中是以被万物之源NSObject类实现的NSKeyValueCodin ...

  2. iOS开发中KVC、KVO简介

    在iOS开发中,KVC和KVO是经常被用到的.可以使用KVC对对象的属性赋值和取得对象的属性值,可以使用KVO监听对象属性值的变化.简单介绍一下KVC和KVO. 一:键值编码(KVC) KVC,全称 ...

  3. [转] iOS (OC) 中 KVC 与 KVO 理解

    转自: http://magicalboy.com/kvc_and_kvo/ KVC 与 KVO 是 Objective C 的关键概念,个人认为必须理解的东西,下面是实例讲解. Key-Value ...

  4. 【原】iOS中KVC和KVO的区别

    在iOS开发中经常会看到KVC和KVO这两个概念,比较可能混淆,特地区分一下 KVC(Key Value Coding) 1> 概述 KVC:Key Value Coding,键值编码,是一种间 ...

  5. iOS - 详细理解KVC与KVO

    详细理解KVC与KVO 在面试的时候,KVC与KVO有些时候还是会问到的,并且他们都是Objective C的关键概念,在这里我们先做一个简单地介绍: (一)KVC: KVC即指:NSKeyValue ...

  6. KVC 与 KVO 理解

    KVC 与 KVO 是 Objective C 的关键概念,个人认为必须理解的东西,下面是实例讲解. Key-Value Coding (KVC) KVC,即是指 NSKeyValueCoding,一 ...

  7. KVC 与 KVO 理解-b

    KVC 与 KVO 是 Objective C 的关键概念,个人认为必须理解的东西,下面是实例讲解. Key-Value Coding (KVC) KVC,即是指 NSKeyValueCoding,一 ...

  8. KVC与KVO的理解

    KVC与KVO是Objective C的关键概念. Key—Value Coding (KVC) 即是指NSKeyValueCoding,一个非正式的Protocol,提供一种机制间接访问对象的属性. ...

  9. KVC与KVO理解

    转载:https://magicalboy.com/kvc_and_kvo/ KVC 与 KVO 理解 KVC 与 KVO 是 Objective C 的关键概念,个人认为必须理解的东西,下面是实例讲 ...

随机推荐

  1. Red Hat快捷键操作

    Red Hat快捷键操作 .使用虚拟控制台 登录后按“Alt+F2”键可以看到“login:”提示符, 这就是第二个虚拟控制台. 一般新安装的Linux有四个虚拟控制台, 可以用“Alt+F1”到“A ...

  2. VMWare虚拟机安装创建虚拟机的使用教程

    VMWare虚拟机安装创建虚拟机的使用教程   在配置虚拟机之前需要安装它,VMWare软件的安装过程比较简单,在安装在之前应该先看下说明文档.下面以VMWare Workstation6.5虚拟机 ...

  3. java多线程有几种实现方法?线程之间如何同步

    java中多线程的实现方法有两种:1.直接继承thread类:2.实现runnable接口: 同步的实现方法有五种:1.同步方法:2.同步代码块:3.使用特殊域变量(volatile)实现线程同步:4 ...

  4. 获取页面中更新删除传过来的id

    利用uri辅助函数 $id=$this->uri->segment(4); 其中segment(参数)  是表示你要截取获得第几个数据.

  5. java笔记知识点总结

    1.switch case default 语句 : switch case 语句是一个条件选择语句,找到相同的case值做为入口,执行后面的程序:若所有的case都不满足,则找default入口:若 ...

  6. SAX与DOM解析XML的区别

    解析xml有四种方法:DOM,SAX,DOM4j,JDOM.     我们主要学了两种:DOM和SAX.     DOM适于解析比较简单的XML而SAX则适于解析较复杂的XML文件.各有各的好. DO ...

  7. ROS 教程之 network:多台计算机之间网络通信(2)

    在上一篇文章中我们已经搭建好了两台计算机间通信的条件,但是每次都需要在新的终端里输入一长串export ROS_MASTER_URI之类的.实际弄起来的时候也不方便,因此在本文中,我们更进一步,简化两 ...

  8. Java获取yahoo天气预报

    学习闲暇之余,写了个获取yahoo天气预报的java小程序,仅供娱乐. 首先我们需要获取您需要查询城市对应的代号,我们可以用HashMap来查询,代码如下: publicstatic HashMap& ...

  9. JavaScript 杂乱的小总结

    基本类型只有String.number.boolean.null.undefined,还有一个Object.存在装箱类型,不过后台自动转换. 通过new创建对象时,如果没有参数,可以省略“()”.-- ...

  10. R语言hist绘图函数

    hist 用于绘制直方图,下面介绍每个参数的作用: 1)x: 用于绘制直方图的数据,该参数的值为一个向量 代码示例: data <- c(rep(1, 10), rep(2, 5), rep(3 ...