KVC与KVO

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KVC与KVO相关的知识,希望对你有一定的参考价值。

Key Value Coding(简称KVC)

KVC的操作方法由NSKeyValueCoding协议提供,而NSObject就实现了这个协议,也就是说ObjC中几乎所有的对象都支持KVC操作,常用的KVC操作方法如下:

  • 动态设置: setValue:属性值 forKey:属性名(用于简单路径)setValue:属性值 forKeyPath:属性路径(用于复合路径,例如Person有一个Account类型的属性,那么person.account就是一个复合属性)
  • 动态读取: valueForKey:属性名 valueForKeyPath:属性名(用于复合路径)

一般model中使用KVC赋值的时候比较多

KVC使用起来比较简单,但是它如何查找一个属性进行读取呢?具体查找规则(假设现在要利用KVC对a进行读取):

  • 如果是动态设置属性,则优先考虑调用setA方法,如果没有该方法则优先考虑搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后仍然没 搜索到则会调用这个类的setValue:forUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能正确设 置);
  • 如果是动态读取属性,则优先考虑调用a方法(属性a的getter方法),如果没有搜索到则会优先搜索成员变量_a,如果仍然不存在则 搜索成员变量a,如果最后仍然没搜索到则会调用这个类的valueforUndefinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的 还是公共的都能正确读取);

KVO:(Key-Value-Observer)键值观察者,是观察者设计模式的一种具体实现

 

KVO触发机制:一个对象(观察者),监测另一对象(被观察者)的某属性是否发生变化,若被监测的属性发生的更改,会触发观察者的一个方法(方法名固定,类似代理方法)

 

KVO使用步骤:

 

1、注册观察者(为被观察者指定观察者以及被观察属性)?

 

2、实现回调方法

 

?3、触发回调方法(被观察属性发生更改)

 

4、移除观察者

 

1 #import "ViewController.h"
 2 
 3 @interface ViewController ()
 4 /// 观察可变数组的改变情况(苹果官方文档不建议对数组进行观察)
 5 @property (nonatomic, strong) NSMutableArray *array;
 6 @end
 7 
 8 @implementation ViewController
 9 
10 - (void)viewDidLoad {
11     [super viewDidLoad];
12     /**
13      *  KVO 键值观察 是观察者设计模式
14      */
15     // 初始化数组
16     self.array = [NSMutableArray array];
17     self.array = [@[@"1"] mutableCopy];
18     // 1、注册观察者
19     // 参数1: 指注册 KVO 通知的对象。观察者必须实现 observeValueForKeyPath:ofObject:change:context: 以对被观察对象的改变做出响应。
20     // 参数2:指相对于被观察者的属性,此值必须不能为 nil。
21     // 参数3:定义的常量值的组合,这些值指定了在发出的观察通知中会包含哪些东西。不同的指定值会导致观察通知中包含的值不同。
22     /**
23      NSKeyValueObservingOptionNew  表示 change 字典中应该包含监听对象的新属性值
24      NSKeyValueObservingOptionOld  表示 change 字典中应该包含监听对象的旧属性值,即改变前的值
25      NSKeyValueObservingOptionInitial  如果设定了该值,在注册观察者的方法返回之前就会发送通知给观察者
26      NSKeyValueObservingOptionPrior  使得被观察对象的值在改变之前和改变之后都会发送通知,而不仅仅是在改变之后发送一个通知
27      */
28     // 参数4:该值可以是任一数据值,会在 observeValueForKeyPath:ofObject:change:context: 中传递给 anObserver,也就是这个参数值与 observeValueForKeyPath:ofObject:change:context: 的 context 参数的值相等
29     [self addObserver:self forKeyPath:@"array" options:NSKeyValueObservingOptionNew context:nil];
30 }
31 
32 // 2、实现回调方法
33 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
34     // 可以进行刷新UI的操作
35     // keyPath 指相对于被监听对象 object 的键路径
36     // object 指键路径 keyPath 所属对象,即被监听对象
37     // change 描述被监听属性的变化信息
38     // context 注册 KVO 时由监听者提供,见上面关于context 的描述
39     NSLog(@"keyPath = %@", keyPath);
40     NSLog(@"object = %@", object);
41     NSLog(@"change = %@", change);
42 }
43 
44 // 3、触发可变数组进行改变
45 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
46     NSArray *subArray = @[@"2", @"3", @"4"];
47     // 根据keyPath获取到可变数组对象
48     // setArray 给可变数组对象设置数据
49     [[self mutableArrayValueForKeyPath:@"array"] setArray:subArray];
50     NSLog(@"========%@", self.array);
51 }
52 
53 // 视图将要消失
54 - (void)viewWillDisappear:(BOOL)animated {
55     // 移除观察者
56     [self removeObserver:self forKeyPath:@"array"];
57 }
58 
59 @end

 

以上是关于KVC与KVO的主要内容,如果未能解决你的问题,请参考以下文章

KVC与KVO

KVC与KVO

KVC 与 KVO

KVC与KVO

iOS 代理与通知,kvc和kvo的区别

iOSKVC 与 KVO