iOS KVO模式

KVO 键值观察机制,当某个对象特定的属性发生变化时能够通知到别的对象。这经常用于 model 和 controller 之间的通信,KVO主要的优点是你不需要在每次属性改变时手动去发送通知。并且它支持为一个属性注册多个观察者。
1.KVO实现机制的原理
KVO 的实现用了一种叫 isa-swizzling 的技术。isa 指针就是指向类的指针,当一个对象的一个属性注册了观察者后,被观察对象的isa指针就指向了一个系统为我们生成的中间类,而不是我们自己创建的类。在这个类中,系统为我们重写了被观察属性的setter方法。可以通过 object_getClass(id obj) 方法获得对象真实的类,在 addObserver 前后分别打印,就可以看到isa指针被指向了一个中间类。似乎都是在原来的类名前面加上 NSKVONotifying_*
isa指针不总是指向真实的类,所以你不应该依赖于 isa 指针来判断这个对象的类型,而应该通过 class 方法来判断对象的类型。

注册 KVO
(1)被观察对象 的属性必须是 KVO Compliant
(2)被观察的对象使用 addObserver:forKeyPath:options:context: 方法注册观察者
(3)观察者必须实现observeValueForKeyPath:ofObject:change:context: 方法

observer 参数是一个观察者对象
keyPath 表示要观察的属性,例如tableView的contentOffset属性
options 决定了提供给观察者change字典中的具体信息有哪些。(change字典是一个提供给观察者的参数,后面会提到)

NSKeyValueObservingOptionOld 表示在change字典中包含了改变前的值。
NSKeyValueObservingOptionNew 表示在change字典中包含新的值。
NSKeyValueObservingOptionInitial 在注册观察者的方法return的时候就会发出一次通知。
NSKeyValueObservingOptionPrior 会在值发生改变前发出一次通知,当然改变后的通知依旧还会发出,也就是每次change都会有两个通知。
context 这个参数可以是一个 C指针,也可以是一个 对象引用,它可以作为这个context的唯一标识,也可以提供一些数据给观察者,一般可以是nil。

属性变化时接收通知
注意:所有的观察者必须实现observeValueForKeyPath:ofObject:change:context: 方法。
当一个被观察属性的值发生改变时,观察者会收到 observeValueForKeyPath:ofObject:change:context: 的消息。。这个方法中的参数和注册观察者方法的参数基本相同,只有一个 change 不同。 change 是一个字典,它里面包含了的信息由注册时的 options 决定。

官方提供了这些key给我们来取到 change 中的value:

NSString *const NSKeyValueChangeKindKey;
NSString *const NSKeyValueChangeNewKey;
NSString *const NSKeyValueChangeOldKey;
NSString *const NSKeyValueChangeIndexesKey;
NSString *const NSKeyValueChangeNotificationIsPriorKey;
NSKeyValueChangeKindKey 这个key包含的value是一个 NSNumber 里面是一个 int,与之对应的是 NSKeyValueChange 的枚举

enum {
NSKeyValueChangeSetting = 1,
NSKeyValueChangeInsertion = 2,
NSKeyValueChangeRemoval = 3,
NSKeyValueChangeReplacement = 4
};
typedef NSUInteger NSKeyValueChange;
当 change[NSKeyValueChangeKindKey] 是 NSKeyValueChangeSetting 的时候,说明被观察属性的setter方法被调用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值