关于KVO

介绍

允许对象监听另一个对象特定属性的改变
KVO 一对一
NSNotificationCenter 一对多
KVO可以监听单个属性的变化,也可以监听集合对象的变化
KVCmutableArrayValueForKey: 获得代理对象, 代理对象的内部对象发生改变时,会调用KVO监听的方法.(NSArray, NSSet)

流程

  1. 注册方法
    addObserver: forKeyPath: options: context:
    
    options: NSKeyValueObservingOptionNew
    NSKeyValueObservingOptionOld
    NSKeyValueObservingOptionInitial 注册观察者后,立即调用一次
    context: 传值
    addObserver: 不会强引用, 所以要注意
  2. 监听方法
    observeValueForKeyPath: ofObject: change: context:
    
    不实现会crash
    change存放KVO属性相关的值
    change中还有NSKeyValueChangeKindKey字段, 和NSKeyValueChangeOldKey平级关系,来提供本次更改的信息,对应NSKeyValueChange的value.
    若被观察者为集合, NSKeyValueChangeKindKey中会包含NSKeyValueChangeInsertion, NSKeyValueChangeRemoval, NSKeyValueChangeReplacement的信息
  3. 移除方法
    removeObserver: forKeyPath: 
    
    需要在观察者消失之前,否则会crash

兼容的调用方式

点语法和set语法

[object setName:@""];
[object setValue:@"" forKey:@"name"];
[document setValue:@"" forKeyPath:@"object.name"];
Object *obj = [[Object alloc] init];
//获取代理集合
NSMutableArray *arrayM = [object mutableArrayValueForKey:@"name"];
[arrayM addObject:obj];

实际应用

KVOmodelcontroller之间进行通信

注意点

KVO中的addObserverremoveObserver成对
initadd,在deallocremove

手动调用KVO

willChangeValueForKey:
didChangeValueForKey:
手动调用这两个方法
控制当前对象自动调用过程,可以重写

+ (BOOL)automaticallyNotifiesObserverForKey:(NSString *)theKey;

实现原理

isa-swizzling
在运行时根据原来创建一个中间类,这个中间类为原类的子类,动态修改当前对象的isa指向中间类,并将class方法重写,返回原来类的Class
NSKVONotifying_xxx 命名中间类

缺点

使用不当容易crash: addremove observer被释放 keyPath传错
keyPath是字符串,修改属性不报错,可以使用NSStringFromSelector(@selector(isFinished)).
KVO不支持block,可以使用Facebook开源的KVOController, 本质是对系统KVO的封装,兼容blockaction

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值