KVC
KVC全称是Key Value Coding,定义在NSKeyValueCoding.h文件中,是一个非正式协议。KVC提供了一种间接访问其属性方法或成员变量的机制,可以通过字符串来访问对应的属性方法或成员变量。包含:getter方法valueForKey:和setter方法setValue:forKey:,以及其衍生的keyPath方法
@interface ViewController ()
@property(nonatomic,copy)NSString *name;
@property(nonatomic,strong)Person *person;
@end
@interface Person : NSObject
@property(nonatomic,assign)NSInteger age;
@end
在使用KVC时,直接将属性名当做key,并设置value,即可对属性进行赋值。
[someBody setValue:@"lise" forKey:@"name"];
keyPath
[someBody setValue:@(18) forKeyPath:@"person.age"];
如果是动态设置属性,则优先考虑调用setA方法,如果没有该方法则优先考虑搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的setValue:forUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确设置);
如果是动态读取属性,则优先考虑调用a方法(属性a的getter方法),如果没有搜索到则会优先搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没搜索到则会调用这个类的valueforUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确读取)
KVO
KVO其实是一种观察者模式,利用它可以很容易实现视图组件和数据模型的分离,当数据模型的属性值改变之后作为监听器 的视图组件就会被激发,激发时就会回调监听器自身。在ObjC中要实现KVO则必须实现NSKeyValueObServing协议,不过幸运的是 NSObject已经实现了该协议,因此几乎所有的ObjC对象都可以使用KVO
系统会在运行期动态地创建该类的一个派生类NSKVONotifying_Person,在这个派生类中重写该类中被观察的属性的 setter 方法。我们知道,重写方法,要调用super
所以KVO的本质就是监听对象的属性进行赋值的时候有没有调用setter方法. 如果有调用setter方法, 就会接收到属性变更的通知, 反之则没有.
KVO的使用步骤也比较简单:
- 通过addObserver: forKeyPath: options: context:为被监听对象(它通常是数据模型)注册监听器
- 重写监听器的observeValueForKeyPath: ofObject: change: context:方法