一.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:的原理
执行setValue:forKey:会按照下面的步骤,如果有就执行,如果就没有就按顺序往下找
1.setKey:
2._setKey:
3.accessInstanceVariablesDirectly(是否可以访问成员变量),默认返回YES,如果返回YES则继续往下走,如果返回NO,则抛出异常**setValue:forUndefinedKey:**
4.按照_key,_isKey,key,iskey的顺序查找成员变量,找到赋值(除赋值以外还会执行willChangeValueForKey和didChangeValueForKey触发KVO),没找到则抛出异常
执行valueForKey:会按照下面的步骤,如果有就执行,如果没有就按顺序往下执行
1.getKey
2.key
3.isKey
4._key
5.accessInstanceVariablesDirectly(是否可以访问成员变量),默认返回YES,如果返回YES则继续往下走,如果返回NO,则抛出异常**setValue:forUndefinedKey:**
6.按照_key,_isKey,key,isKey的顺序查找成员变量,找到则返回其值,找不到则抛出异常
三.KVC会触发KVO吗?会