iOS中KVC

作者: Torin76 | 来源:发表于2018-07-27 12:50 被阅读9次

想必大家都知道可以通过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方式允许通过字符串行驶来操作对象的属性,这个字符串既可以是常量,也可以是变量,因此具有极高的灵活性。

相关文章

网友评论

      本文标题:iOS中KVC

      本文链接:https://www.haomeiwen.com/subject/qaocmftx.html