使用KVO监听数组长度的变化

638 阅读2分钟
在处理App的一个bug时, 遇到需要监听可变数组长度的变化, 同时刷新UI界面。发现它与我们监听对象属性的变化不一样,后来查了一下资料,果真是自己粗心了,这里有知识盲区,特此记录一下。
KVO全称是Key-value Observing,翻译过来就是: 键值观察。提供了一种当其它对象属性被修改的时候能通知当前对象的机制。它的通常使用方法在此不再赘述, 比如person对象注册控制器为观察者,监听自身age属性的变化,当自身age属性发生变化的时候,控制器对应做相应的需求处理。
对于KVO的底层原理,我们都知道,苹果官方使用isa-swizzling技术实现。Objective-C依托于强大的run time机制来实现KVO。当我们第一次观察某个对象的属性时,runtime会创建一个新的继承自这个对象的class的subclass。在这个新的subclass中,它会重写所有被观察的key的setter,然后将对象的isa指针指向新创建的class(这个指针告诉Objective-C运行时某个对象到底是什么类型的)。所以实例对象神奇地变成了新的子类的实例。完成以上操作后,通过调用setter方法进行相关属性的变化时,操作的就是这个中间的子类。也就是说KVO实际上是通过settet方法监听的属性。
监听数组长度的变化与监听对象属性的变化是不一样的。监听对象属性的变化,只需要对象属性有对应的setter方法,使用一般的KVO步骤即可达到监听对象属性变化的目的。监听数组长度的变化,则涉及到的是集合属性的监听。
对于集合的KVO,我们需要了解的一点是,KVO旨在观察关系(relationship)而不是集合。对于不可变集合属性,我们更多的是把它当成一个整体来监听,而无法去监听集合中的某个元素的变化;对于可变集合属性,实际上也是当成一个整体,去监听它整体的变化,如添加、删除和替换元素。
①监听集合整体的变化

2.jpg
3.jpg ②如果想监听集合中数据的变化,如添加、删除和替换元素该如何处理呢?向可变数组中添加元素,这种处理方式没有效果。见下图 image.png 我们知道KVO键值监听实现的基础是KVC 所以对于可变集合,我们不使用valueForKey:来获取对象,而是使用以下方法:

-(NSMutableArray *)mutableArrayValueForKey:(NSString *)key;

分别对可变数组中的元素进行添加、删除、替换等效果 image.png image.png