Objective-C中的KVC与KVO(上)
来源:互联网 发布:linux mint 18很卡 编辑:程序博客网 时间:2024/06/05 18:37
Objective-C中的KVC与KVO是两种比较重要的技术,这里简要介绍一下这两者的使用方法。
一、KVC
《iOS程序开发方法与实践》中介绍了KVC(Key–Value Coding,键值编码)的基本内容。
简要来说,KVC提供了一种在运行时而非编译时动态访问对象属性与成员变量的方式,也就是说,我们可以用字符串的内容作为属性名称或者成员变量名称进行访问。这种特性有些类似于其他高级编程语言中的反射。
举个例子,例如我们创建了一个类ClassA,其中定义了3个属性p1、p2和p3,以及1个实例方法getValueByPropertyName:,代码如下:
- @interface ClassA : NSObject
- @property (nonatomic) int p1;
- @property (nonatomic) int p2;
- @property (nonatomic) int p3;
- - (int)getValueByPropertyName:(NSString*)pName;
- @end
- @implementation ClassA
- @synthesize p1 = _p1, p2 = _p2, p3 = _p3;
- ...
- - (int)getValueByPropertyName:(NSString*)pName
- {
- if([pName isEqualToString:@"p1"])
- {
- return self.p1;
- }
- else if([pName isEqualToString:@"p2"])
- {
- return self.p2;
- }
- else if([pName isEqualToString:@"p3"])
- {
- return self.p3;
- }
- return 0;
- }
- @end
方法getValueByPropertyName:用于通过字符串来访问对应的属性值。如果我们想要向ClassA添加几个属性,那么这个方法就还需要添加几个else if语句。而如果使用KVC就会方便许多,代码如下:
- - (int)getValueByPropertyName:(NSString*)pName
- {
- NSNumber* pNumber = [self valueForKey:pName];
- return [pNumber intValue];
- }
这里有几点需要注意,首先这里的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:,我们就可以在一条语句中接连调用制定的属性。请看下面的例子:
- @interface Product : NSObject
- @property NSString* name;
- @end
- @implementation Product
- @synthesize name = _name;
- - (void)dealloc
- {
- self.name = nil;
- [super dealloc];
- }
- @end
- @interface Manufacturer : NSObject
- @property Product* product;
- @end
- @implementation Manufacturer
- @synthesize product = _product;
- -(void)dealloc
- {
- self.product = nil;
- [super dealloc];
- }
- @end
- int main(int argc, const char * argv[])
- {
- @autoreleasepool
- {
- Manufacturer* apple = [[[Manufacturer alloc] init] autorelease];
- Product* iPhone4S = [[[Product alloc] init] autorelease];
- iPhone4S.name = @"iPhone 4S";
- apple.product = iPhone4S;
- Manufacturer* micro$oft = [[[Manufacturer alloc] init] autorelease];
- Product* win8 = [[[Product alloc] init] autorelease];
- win8.name = @"Windows 8";
- micro$oft.product = win8;
- NSArray* manufacturerArray = [NSArray arrayWithObjects:apple, micro$oft, nil];
- NSArray* productNameArray = [manufacturerArray valueForKeyPath:@"product.name"];
- NSLog(@"productNameArray:\n%@", productNameArray);
- }
- return 0;
- }
- productNameArray:
- (
- "iPhone 4S",
- "Windows 8"
- )
使用KVC的好处是非常灵活,但同时也丢失了编译时检查。
在下一篇中,我将会介绍KVO的使用方法。
- Objective-C中的KVC与KVO(上)
- Objective-C中的KVC与KVO(上)
- Objective-C中的KVC与KVO(上)
- Objective-C中的KVC与KVO(上)
- Objective-c中的KVC、KVO
- Objective-C中的KVC和KVO
- Objective-C KVO&KVC
- Objective-C KVC&KVO
- Objective-c KVO and KVC
- Objective-c KVO,KVC例子
- Objective-C KVC - KVO
- Objective-C之KVC、KVO
- Objective-C之KVC、KVO
- LHF Objective-C语法(13)KVC KVO
- Objective-c KVC and KVO and 通知
- Objective-C 中关于KVC\KVO
- Objective-C语法入门之KVC & KVO
- [iOS]Objective-C之KVC、KVO
- 分享一些高清javascript书
- Golang 工程自管理
- 使用程序内购买(IAP)的应用程序在提交时的注意事项,防止审核被拒
- FZU 1475不同的单词数
- 轻松掌握MySQL数据库锁机制的相关原理
- Objective-C中的KVC与KVO(上)
- 第四章
- java中变量的使用规则
- [转帖]MySQL的sum函数返回的类型
- Objective-C中的类别(Category)
- SCOMRM跟踪
- SCORM 基础知识
- ObjectiveC中的赋值,对象拷贝,浅拷贝与深拷贝
- Notification通知栏创建及高级功能