KVC
来源:互联网 发布:sas编程 编辑:程序博客网 时间:2024/05/01 12:18
转自:http://www.cnblogs.com/kenshincui/p/3871178.html 崔江涛(KenshinCui)
概述
由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby、Python的动态特性,例如动态类型、动态加载、动态绑定等。今天我们着重介绍ObjC中的键值编码(KVC)、键值监听(KVO)特性:
- 键值编码KVC
- 键值监听KVO
键值编码KVC
我们知道在C#中可以通过反射读写一个对象的属性,有时候这种方式特别方便,因为你可以利用字符串的方式去动态控制一个对象。其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的动态读写,这种方式就是Key Value Coding(简称KVC)。
KVC的操作方法由NSKeyValueCoding协议提供,而NSObject就实现了这个协议,也就是说ObjC中几乎所有的对象都支持KVC操作,常用的KVC操作方法如下:
- 动态设置: setValue:属性值 forKey:属性名(用于简单路径)、setValue:属性值 forKeyPath:属性路径(用于复合路径,例如Person有一个Account类型的属性,那么person.account就是一个复合属性)
- 动态读取: valueForKey:属性名 、valueForKeyPath:属性名(用于复合路径)
下面通过一个例子来理解KVC
Account.h
//
// Account.h
// KVCAndKVO
//
// Created by Kenshin Cui on14-2-16.
// Copyright (c) 2014年 Kenshin Cui. All rightsreserved.
//
#import<Foundation/Foundation.h>
@interfaceAccount :NSObject
#pragmamark -属性
#pragmamark余额
@property(nonatomic,assign)floatbalance;
@end
Account.m
//
// Account.m
// KVCAndKVO
//
// Created by Kenshin Cui on14-2-16.
// Copyright (c) 2014年 Kenshin Cui. All rightsreserved.
//
#import"Account.h"
@implementation Account
@end
Person.h
//
// Person.h
// KVCAndKVO
//
// Created by Kenshin Cui on14-2-16.
// Copyright (c) 2014年 Kenshin Cui. All rightsreserved.
//
#import<Foundation/Foundation.h>
@classAccount;
@interfacePerson :NSObject{
@private
int _age;
}
#pragmamark -属性
#pragmamark姓名
@property(nonatomic,copy)NSString *name;
#pragmamark账户
@property(nonatomic,retain) Account*account;
#pragmamark -公共方法
#pragmamark显示人员信息
-(void)showMessage;
@end
Person.m
//
// Person.m
// KVCAndKVO
//
// Created by Kenshin Cui on14-2-16.
// Copyright (c) 2014年 Kenshin Cui. All rightsreserved.
//
#import"Person.h"
@implementation Person
#pragmamark -公共方法
#pragmamark显示人员信息
-(void)showMessage{
NSLog(@"name=%@,age=%d",_name,_age);
}
@end
main.m
//
// main.m
// KVCAndKVO
//
// Created by Kenshin Cui on14-2-16.
// Copyright (c) 2014年 Kenshin Cui. All rightsreserved.
//
#import<Foundation/Foundation.h>
#import "Person.h"
#import "Account.h"
intmain(intargc,const char* argv[]){
@autoreleasepool {
Person *person1=[[Personalloc]init];
[person1setValue:@"Kenshin"forKey:@"name"];
[person1 setValue:@28 forKey:@"age"];//注意即使一个私有变量仍然可以访问
[person1showMessage];
//结果:name=Kenshin,age=28
NSLog(@"person1'sname is :%@,age is :%@",person1.name,[person1 valueForKey:@"age"]);
//结果:person1's nameis :Kenshin,age is :28
Account *account1=[[Accountalloc]init];
person1.account=account1;//注意这一步一定要先给account属性赋值,否则下面按路径赋值无法成功,因为account为nil,当然这一步骤也可以写成:[person1setValue:account1 forKeyPath:@"account"];
[person1setValue:@100000000.0 forKeyPath:@"account.balance"];
NSLog(@"person1'sbalance is :%.2f",[[person1 valueForKeyPath:@"account.balance"]floatValue]);
//结果:person1'sbalance is :100000000.00
}
return0;
}
KVC使用起来比较简单,但是它如何查找一个属性进行读取呢?具体查找规则(假设现在要利用KVC对a进行读取):
- 如果是动态设置属性,则优先考虑调用setA方法,如果没有该方法则优先考虑搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的setValue:forUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确设置);
- 如果是动态读取属性,则优先考虑调用a方法(属性a的getter方法),如果没有搜索到则会优先搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的valueforUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确读取);
- KVC
- Kvc....
- KVC
- KVC
- KVC
- KVC
- KVC
- kvc
- KVC
- KVC
- KVC
- KVC
- KVC
- KVC
- KVC
- KVC
- KVC
- kvc
- 键盘VK键值列表
- SIFT检测特征点之找到主方向
- 在centos6上搭建git服务器
- 【牛腩新闻发布系统 一】如何高效写代码
- 使用PHP制作 简易员工管理系统之七(MVC实现用户信息增、删、改、查)
- KVC
- 开始刷leetcode day40:Set Matrix Zeroes
- 技术 blog20 之 Java正则表达式 by 八戒
- Android之各种Adapter
- 我的Java开发学习之旅------>Java使用Fork/Join框架来并行执行任务
- #leetcode#Multiply Strings
- mark—android返回键
- 《现代礼仪》总结五
- ASPxPopupControl 关闭对话框前后台用法