Objective-C 之KVC详解


一、KVC深入理解

a. 概念:

KVC:指的是 key valued coding 键值编码。

b. 赋值:

使用KVC间接修改对象属性时,系统会自动判断对象属性的类型,并完成转换。

c. 取值:

KVC按照键值路径取值时,如果对象不包含指定的键值,会自动进入对象内部层层深入,获取对应的键值。

d. 注意:

KVC是一种间接修改/读取对象属性的一种方式,在使用时需要注意,键值名称在对象属性中必须存在,否则会崩溃!

e. 操作方法:

KVC的操作方法由NSKeyValueCoding协议提供,而NSObject就实现了这个协议,也就是说ObjC中几乎所有的对象都支持KVC操作,常用的KVC操作方法如下:

 1> 动态设置: 

setValue:属性值 forKey:属性名

setValue:属性值 forKeyPath:属性路径(常用于复合路径)

 2> 动态读取: 

valueForKey:属性名 

valueForKeyPath:属性路径(常用于复合路径)

f. 具体实现过程:

KVC 使用起来比较简单,假设现在要利用 KVC 对属性 a 进行读取:

 1> 赋值过程:

如果是动态设置属性,则优先考虑调用 setA 方法,如果没有该方法则优先考虑搜索成员变量 _a,如果仍然不存在则搜索成员变量 a,如果最后仍然没搜索到则会调用这个类的

setValue:forUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确设置);

 2> 取值过程:

如果是动态读取属性,则优先考虑调用 a 方法(属性 a 的getter方法),如果没有搜索到则会优先搜索成员变量 _a,如果仍然不存在则搜索成员变量 a,如果最后仍然没搜索到

则会调用这个类的 valueforUndefinedKey: 方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确读取)。


二、KVC具体使用示例及打印日志结果

#import <Foundation/Foundation.h>
#import "Dog.h"
@interface People : NSObject
{
    @private
    int _age;
    double height;
}
@property (nonatomic,copy) NSString *name;
@property (nonatomic,strong) Dog *dog;
@end

#import <Foundation/Foundation.h>
@interface Dog : NSObject
@property (nonatomic,copy) NSString *color;
@end

#import "ViewController.h"
#import "People.h"
#import "Dog.h"
@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    People *p1 = [[People alloc] init];
    Dog *dog = [[Dog alloc] init];
    p1.dog = dog;
    
    p1.name = @"huawuque";
    [p1 setValue:@18 forKey:@"age"];
    [p1 setValue:@1.8 forKey:@"height"];
    [p1 setValue:@"yellow" forKeyPath:@"dog.color"];
    
    NSLog(@"name:   %@",p1.name);
    NSLog(@"age:    %d",[[p1 valueForKeyPath:@"age"] intValue]);
    NSLog(@"height: %.2f",[[p1 valueForKeyPath:@"height"] doubleValue]);
    NSLog(@"color:  %@",[p1 valueForKeyPath:@"dog.color"]);
}
@end


    // 模型属性作为key值转成字典,但是这里好像不能传入keyPath,会崩溃
    NSDictionary *dict = [p2 dictionaryWithValuesForKeys:@[@"age",@"height",@"name"]];
    NSLog(@"dict:%@",dict);


    NSArray *persons = @[p1,p2];
    // 一次性取出 persons 数组里面所有的 person 对象的属性 name 的值存放于数组中
    NSArray *names = [persons valueForKeyPath:@"name"];
    NSLog(@"names:%@",names);


    People *p3 = [[People alloc] init];
    NSDictionary *dic = @{@"name":@"yaoyue",@"age":@25,@"height":@16};
    // 字典转模型
    [p3 setValuesForKeysWithDictionary:dic];
    // 为了跟踪 People 类的输出日志,重写了 People 类的 description 方法
    NSLog(@"p3: %@",p3);




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值