聊聊KVO

iOS中的KVO用起来还是蛮爽的,特别适合用在Model更改后刷新UI等操作,可以很方便的监听一个对象属性值的变化,只需要对目标对象添加观察者即可

聊聊KVO_第1张图片

了解了基本操作后,我们再深入了解下它是如何实现的

那我们从addObserver函数开始,函数接受四个参数,分别是:

  • observer:注册KVO的对象,且需要实现了observeValueForKeyPath:ofObject:change:context:方法

  • keyPath: 接受消息的关键路径,不能为空,可在接受函数中通过判断改值,筛选被观察的对象

  • options:设置通知方式

  • context:传递给接受函数的内容,可为nil
    其他没什么说的,主要说一下options这个参数,该参数接受NSKeyValueObservingOptions类型的枚举,总共有一下四个类型:

  • NSKeyValueObservingOptionNew //在接收器chagne参数中传递被修改后的新值

  • NSKeyValueObservingOptionOld //在接收器change参数中传递被修改前的旧值

  • NSKeyValueObservingOptionInitial //在注册观察者时,会先向接受者发送一次消息

  • NSKeyValueObservingOptionPrior //在被观察对象修改前和修改后,都向接收器发送一次消息


了解了注册观察者的详细后,下面我们来对比下注册观察者和未注册观察的内存关系对比

未注册的对象

聊聊KVO_第2张图片

从图中我们可以看到,未添加的KVO监

听的对象,isa直接指向它的类Person
下面看下注册了观察者的对象

聊聊KVO_第3张图片

可以看到在对象和类中间多了一个NSKVONotifyingPersonClass,该类是由runtime动态生成,在我们去给对象sam的age属性赋值时,setAge方法会调用Foundation中的_NSSetIntValueAndNotify方法,_NSSetIntValueAndNotify方法内部会依次调用

  • willChangeValueForKey

  • super setAge

  • didChangeValueForKey

(如果需要验证以上调用顺序,我们可以在Person内重写以上方法验证)

随后会向接收器发送消息,也就是我们上面所说的observeValueForKeyPath:ofObject:change:context监听函数。


你可能感兴趣的:(聊聊KVO)