OC中的KVC和KVO

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


image.png

系统会在运行期动态地创建该类的一个派生类NSKVONotifying_Person,在这个派生类中重写该类中被观察的属性的 setter 方法。我们知道,重写方法,要调用super

所以KVO的本质就是监听对象的属性进行赋值的时候有没有调用setter方法. 如果有调用setter方法, 就会接收到属性变更的通知, 反之则没有.

KVO的使用步骤也比较简单:

  1. 通过addObserver: forKeyPath: options: context:为被监听对象(它通常是数据模型)注册监听器
  2. 重写监听器的observeValueForKeyPath: ofObject: change: context:方法

你可能感兴趣的:(OC中的KVC和KVO)