想必大家都知道可以通过setter、gettter方法来设置和修饰对象的属性,也知道如何通过简化的点语法来设置、修饰对象的属性。实际上,Objecttive-C还支持一种灵活的操作方式,这种方式允许以字符串形式间接操作对象的属性,这种方式的全称是Key Value Coding(简称KVC),即键值编码。
简单的KVC
最基本的KVC由NsKeyValueCoding协议提供支持,最基本的操作属性有如下两个方法
- setValue
- valueForKey
下面定义一个Person对象,定义三个属性
@interface Person : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *age;
@property(nonatomic,assign)NSInteger count;
@end
在Controller中使用
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Person *p = [Person new];
[p setValue:@"张三" forKey:@"name"];
[p setValue:@"18" forKey:@"age"];
[p setValue:@"175" forKey:@"height"];
// [p setValue:nil forUndefinedKey:@"count"];
NSLog(@"age=%@,name=%@",[p valueForKey:@"age"],[p valueForKey:@"name"]);
}
打印结果如下:
018-07-27 11:50:45.174364+0800 KVCAndKVO[33487:1323881] age=18,name=张三
下面咋们把上面的代码注释的地方去掉注释
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Person *p = [Person new];
[p setValue:@"张三" forKey:@"name"];
[p setValue:@"18" forKey:@"age"];
[p setValue:@"175" forKey:@"height"];
NSLog(@"age=%@,name=%@",[p valueForKey:@"age"],[p valueForKey:@"name"]);
}
你会发现程序出现崩溃,是的没错我们设置的key对象Person没有定义所以出现崩溃,下面让我来看看崩溃的时候执行了什么方法,如下代码在Person.m文件中重写- (void)setValue:(id)value forUndefinedKey:(NSString *)key方法,是的我们打印会发现会执行该方法,当设置Key的时候没有该Key的时候就会执行该方法:setValue:forUndefinedKey。
#import "Person.h"
@implementation Person {
NSString *_height;
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
NSLog(@"属性不存在");
}
我们可以肯定知道在Person.h文件增加一个height属性肯定可以设置,我们在Person.m文件定义一个_height,再setvalue forkey
[p setValue:@"175" forKey:@"height"];
打印可以得到175
说到这里先把结果总结出来:
对于setValue:属性值 forKey@"name";代码,底层的执行机制如下:
<1>程序优先考虑调用 "setName"方法即Setter方法
<2>如果没有setName方法,KVC机制会搜索该类名为_name的成员变量
<3>r如果既没有setName方法和_name的成员变量,KVC机制会搜索该类名为name的成员变量
有了setter和getter为什么还要用KVC?
实际上,通过KVC操作对象的性能比通过setter和getter方法的性能更差,使用KVC编程的优势更加简洁,更适合提炼一些通用代码。由于KVC方式允许通过字符串行驶来操作对象的属性,这个字符串既可以是常量,也可以是变量,因此具有极高的灵活性。
网友评论