iOS开发--Objective-C之KVC
2015-06-14 22:07
555 查看
首先来了解一下什么KVC,KVC就是我们平时所说的键值编码,简单的理解就是可以通过一个key值,修改对象的与这个key对应属性的值,也可以根据该key获取对象的与这个key相对应属性的值。
KVC的操作方法由NSKeyValueCoding协议提供,而NSObject就实现了这个协议,也就是说ObjC中几乎所有的对象都支持KVC操作,常用的KVC操作方法如下:
设置属性的值:
- (void)setValue:(id)value forKey:(NSString *)key;
参数说明:value:想要设置的值, key:键值
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
参数说明:value:想要设置的值, keyPath:键值路径
这个两个方法有什么区别呢?
setValue: forKey:只能修改对象的直接属性,不能修改对象间接属性(对象属性的属性值),setValue: forKeyPath:可以修改间接属性的值,当然也可以修改直接属性的值。
换言之,setValue: forKey:只支持单级映射,而setValue: forKeyPath:支持多级映射。
获取属性的值:
- (id)valueForKey:(NSString *)key; // 只能获取对象的直接属性,
- (id)valueForKeyPath:(NSString *)keyPath; // 可获取对象的间接属性
说明:通过KVC的方式不仅对对象的共有属性(在.h文件声明的属性)有效,对私有属性(在.m文件声明的属性)也有效。
下面通过代码来进一步认识KVC
Dog类
Dog.h
Dog.m
Person类
Person.h
Person.m
那KVO内部到底是如何实现的呢?
设置属性,优先查找属性的set方法,如果没有该方法则优先考虑搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的setValue:forUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确设置);
读取属性,优先查找属性的get方法,如果没有搜索到则会优先搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的valueforUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确读取);
KVC的操作方法由NSKeyValueCoding协议提供,而NSObject就实现了这个协议,也就是说ObjC中几乎所有的对象都支持KVC操作,常用的KVC操作方法如下:
设置属性的值:
- (void)setValue:(id)value forKey:(NSString *)key;
参数说明:value:想要设置的值, key:键值
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
参数说明:value:想要设置的值, keyPath:键值路径
这个两个方法有什么区别呢?
setValue: forKey:只能修改对象的直接属性,不能修改对象间接属性(对象属性的属性值),setValue: forKeyPath:可以修改间接属性的值,当然也可以修改直接属性的值。
换言之,setValue: forKey:只支持单级映射,而setValue: forKeyPath:支持多级映射。
获取属性的值:
- (id)valueForKey:(NSString *)key; // 只能获取对象的直接属性,
- (id)valueForKeyPath:(NSString *)keyPath; // 可获取对象的间接属性
说明:通过KVC的方式不仅对对象的共有属性(在.h文件声明的属性)有效,对私有属性(在.m文件声明的属性)也有效。
下面通过代码来进一步认识KVC
Dog类
Dog.h
@interface Dog : NSObject // 公有属性 @property (nonatomic, copy) NSString *name; // 狗的名字 @end</span>
Dog.m
@interface Dog () // 私有属性 @property (nonatomic, assign) CGFloat weight;// 狗的重量 @end
Person类
Person.h
@interface Person : NSObject // 公有属性 @property (nonatomic, copy) NSString *phoneNum; // 人的身高 @property (nonatomic, strong) Dog *dog; // 人有一条狗 @end
Person.m
@interface Person() // 私有属性 @property (nonatomic, assign) int age; // 人的年龄 @end
#import <Foundation/Foundation.h> #import "Person.h" #import "Dog.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [[Person alloc] init]; // 通过KVC方式 修改一个对象的成员属性, [p setValue:@"10086" forKey:@"phoneNum"]; [p setValue:@(26) forKey:@"age"]; // 私有成员属性 //通过KVC方式 访问一个对象的成员属性 NSString *pPhoneNum = [p valueForKey:@"phoneNum"]; int pAge = [[p valueForKey:@"age"] intValue]; // 私有成员属性 NSLog(@"pPhoneNum = %@, pAge = %d", pPhoneNum, pAge); // 可以通过KVC修改和访问一个对象的属性的属性 (多级映射) Dog *d = [[Dog alloc] init]; p.dog = d; [p setValue:@"HaQiDog" forKeyPath:@"p.dog.name"]; [p setValue:@(10.7) forKeyPath:@"p.dog.weight"]; // 私有成员属性 NSString *dName = [p valueForKeyPath:@"p.dog.name"]; CGFloat dWeight = [[p valueForKeyPath:@"p.dog.weight"] floatValue]; // 私有成员属性 NSLog(@"dName = %@, dWeight = %f", dName, dWeight); } return 0; }
那KVO内部到底是如何实现的呢?
设置属性,优先查找属性的set方法,如果没有该方法则优先考虑搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的setValue:forUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确设置);
读取属性,优先查找属性的get方法,如果没有搜索到则会优先搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的valueforUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确读取);
相关文章推荐
- Objective-C 知识点总结
- Objective-C面试题2
- Objective-C面试题
- [Objective-C] 006_Protocol(协议)
- Object-c-数组的使用
- 关于等待多长时间会引发ORA-04021: timeout occurred while waiting to lock object错误的猜测
- objective-c中线程编程一例
- objective-c中线程编程一例
- objective-c中线程编程一例
- Object-C中需要注意的小细节
- 使用Object#tap使代码更优雅
- 学习笔记(objective-c)-重写description方法
- WebSocket使用javax.websocket.RemoteEndpoint.Basic.sendObject(Object arg0)向页面方法发送对象
- java笔记10 多态 Object类
- UGUI - 判断是否点击在UI 上 Bug,IsPointerOverGameObject()在移动端检测失败
- ObjectOutStream的reset方法
- 学习笔记(objective-c)-判断指针变量的实际类型
- Python标准库:内置函数vars([object])
- Python标准库:内置函数vars([object])
- 学习笔记(objective-c)-多态