KVC原理

KVC基本的使用

  1. setValue:forKey:,setValue:forKeyPath:
    Student *aStudent = [[Student alloc] init];
    [aStudent setValue:@"123" forKey:@"ivar"];
    [aStudent setValue:[[Test alloc] init] forKey:@"test"];
    [aStudent setValue:@"test123" forKeyPath:@"test.name"];
    NSLog(@"aStudent = %@",aStudent);

setValue:forKey:只支持一级属性
setValue:forKeyPath: 支持多级属性,也支持一级属性
2. valueForKey:,valueForKeyPath:

    NSString *ivar = [aStudent valueForKey:@"ivar"];
    NSString *name = [aStudent valueForKeyPath:@"test.name"];

valueForKey:只支持一级属性
valueForKeyPath: 支持多级属性,也支持一级属性

  1. KVC可以获取.h文件.m文件的属性(runtime也一样)

KVC底层原理

  1. 先调用key对应的set方法
#import "Student.h"
@implementation Student
- (void)setName:(NSString *)name{
    _name = @"test";
}
@end

Student *aStudent = [[Student alloc] init];
[aStudent setValue:@"000" forKey:@"name"];
NSLog(@"name = %@",aStudent.name);

如上方法验证,首先重写了name的setter方法,并打一个断点。之后利用kvc给name属性赋值。程序运行后发现走了断点,并打印了name属性的值是test。说明了kvc首先调用了属性的setter方法。
2. 如果setter方法没有将会查找属性,直接属性赋值

#import "Student.h"
@implementation Student
@dynamic name;
@end
- (void)viewDidLoad {
    [super viewDidLoad];

    Student *aStudent = [[Student alloc] init];
    [aStudent setValue:@"000" forKey:@"name"];
    NSLog(@"name = %@",aStudent.name);
}

如上方法验证,首先将name属性声明为@dynamic。即不自动课程setter方法。之后进行kvc赋值。发现崩溃。说明了kvc在找不到setter方法后将直接对属性赋值,这时候最终调用的是setter方法,应为找不到setter方法,所以崩溃。
3. 如果找不到属性将会找成员变量,直接对成员变量赋值

@interface Student : NSObject <YYModel>
{
    NSString *ivar;
}
- (void)viewDidLoad {
    [super viewDidLoad];

    Student *aStudent = [[Student alloc] init];
    [aStudent setValue:@"000" forKey:@"ivar"];
    NSLog(@"aStudent = %@",aStudent);
}

如上方法验证,首先定义一个ivar成员变量。之后进行kvc对ivar赋值。然后打印aStudent对象,在这里设置一个断点会发现aStudent对象内部的ivar成员变量被成功赋值了000字串。说明了,kvc在找不到属性后会找相应的成员变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值