iOS底层学习——KVC

简单使用

/// 创建学生对象
@interface DDStudent : NSObject
@property (nonatomic, strong) NSString *name;
@end
/// 创建人对象
@interface DDPerson : NSObject
@property (nonatomic, assign) int age;
/// 把学生对象设置为属性
@property (nonatomic, strong) DDStudent *student;
@end


/// 实现
int main(int argc, const char * argv[]) {
    @autoreleasepool {
    	/// 创建实例
        DDPerson *person = [[DDPerson alloc] init];
        person.student = [[DDStudent alloc] init];
        /// KVC设置属性的值
        [person setValue:@10 forKey:@"age"];
        /// 注意如果属性是复杂对象,就应该使用forKeyPath赋值
        [person setValue:@"小明" forKeyPath:@"student.name"];
        
        NSLog(@"age = %d,  studentName = %@", person.age, person.student.name);
        /// 结果:age = 10,  studentName = 小明
    }
    return 0;
}

实现原理

赋值原理

KVC赋值调用setValue:forKey: 或者setValue:forKeyPath:具体流程是如何实现的

  1. 首先按照顺序查找setKey:和_setKey: 方法,如果查找到则传入参数,调用方法,如果没有找到走第二步
  2. 查看accessInstanceVariableDirectily方法返回值,如果返回NO,则报错NSUnknownKeyException,意思就是没有找到这个Key。如果上一步返回YES,走第三步
  3. 按顺序查找 _key、_isKey、key、_isKey 四个成员变量,如果找到了那么就直接赋值,如果没有则报错NSUnknownKeyException,意思就是没有找到这个Key

具体流程可看下图

在这里插入图片描述
上图就是KVC赋值的过程,通过上图我们可以很清楚的看到是如何赋值的

取值原理

调用valueForKey:

  1. 首先按循序查找getKey、key、isKey、_Key方法,如果查找到了则直接调用方法。如果没有查找到走第二步
  2. 跟赋值第二步一样

取值过程我们也可以看这张图
在这里插入图片描述

补充——KVC能触发KVO吗

如果一个属性添加了KVO,那么使用KVC是可以触发KVO。由于触发KVO的条件就是调用了Setter方法,而KVC内部实现的时候也是调用了setter方法的。还有一点就是在第一步就算没有找到setter方法,那么在第二步给成员变量赋值的时候会自动调用willChangeValueForKey:和didChangeValueForKey: 相当于手动触发了KVO。综上所述KVC是可以触发KVO的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值