iOS-KVC的取值赋值

479 阅读1分钟

一.KVC的使用

我们经常使用的KVC有4个API

- (void)setValue:(nullable id)value forKey:(NSString *)key
- (nullable id)valueForKey:(NSString *)key;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
- (nullable id)valueForKeyPath:(NSString *)keyPath;

这四个方法都是对象方法,凡是继承自NSObject的对象都可以使用,如果是设置某个属性或者变量,直接用forKey,如果是根据路径进行设置(例如某个属性是一个对象,要设置属性的某个属性),请使用forKeyPath.例:

@interface Person : NSObject

@property (nonatomic, assign) int age;

@property (nonatomic, strong) Student *stu;

@end

@interface Student : NSObject

@property (nonatomic, assign) int height;

@end

我们要给Person对象设置age属性,就可以这样写

Person *p = [[Person alloc] init];

[p setValue:@10 forKey:@"age"];

我们要给Person对象里的stu属性设置height,就可以这样写

Person *p = [[Person alloc] init];

p.stu = [[Student alloc] init];

[p setValue:@170 forKeyPath:@"stu.height"];

二.setValue:forKey:和valueForKey:的原理

截屏2022-03-25 下午2.20.12.png

执行setValue:forKey:会按照下面的步骤,如果有就执行,如果就没有就按顺序往下找
1.setKey:
2._setKey:
3.accessInstanceVariablesDirectly(是否可以访问成员变量),默认返回YES,如果返回YES则继续往下走,如果返回NO,则抛出异常**setValue:forUndefinedKey:**
4.按照_key,_isKey,key,iskey的顺序查找成员变量,找到赋值(除赋值以外还会执行willChangeValueForKey和didChangeValueForKey触发KVO),没找到则抛出异常

截屏2022-03-25 下午2.20.23.png

执行valueForKey:会按照下面的步骤,如果有就执行,如果没有就按顺序往下执行
1.getKey
2.key
3.isKey
4._key
5.accessInstanceVariablesDirectly(是否可以访问成员变量),默认返回YES,如果返回YES则继续往下走,如果返回NO,则抛出异常**setValue:forUndefinedKey:**
6.按照_key,_isKey,key,isKey的顺序查找成员变量,找到则返回其值,找不到则抛出异常

三.KVC会触发KVO吗?会