版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.09.13 |
前言
KVO
具有更强大的功能,是苹果给我们的一个回调机制,在某个对象注册监听者后,在被监听的对象发生改变时,对象会发送一个通知给监听者,以便监听者执行回调操作。接下来几篇就详细的解析一下KVO。
基本基础及原理
键值观察提供了一种机制,允许将对象的更改通知给其他对象的特定属性。 它在应用程序中的模型和控制器层之间的通信特别有用。 (在OS X中,控制器层绑定技术极大地依赖于键值观察。)控制器对象通常观察模型对象的属性,而视图对象通过控制器观察模型对象的属性。 然而,此外,模型对象可以观察其他模型对象(通常用于确定依赖值何时改变)甚至本身(再次确定依赖值何时改变)。
您可以观察属性,包括简单属性,一对一关系和多对多关系。 许多关系的观察者被告知所做的改变的类型以及变更涉及的对象。
一个简单的例子说明了KVO如何在您的应用程序中有用。 假设一个Person对象与一个Account对象交互,代表该人在一家银行的储蓄账户。 个人实例可能需要了解帐户实例的某些方面如何变化,例如余额或利率。
如果这些属性是帐户的公共属性,则人员可以定期轮询帐户以发现更改,但这当然是低效的,并且通常是不切实际的。 更好的方法是使用KVO,类似于发生更改时收到中断的人员。
要使用KVO,首先必须确保观察到的对象,在这种情况下的帐户符合KVO。 通常,如果您的对象从NSObject继承并以通常的方式创建属性,则对象及其属性将自动符合KVO标准。 也可以手动执行合规性。 KVO合规性描述了自动和手动键值观察之间的区别,以及如何实现两者。
接下来,您必须使用所观察到的实例,注册您的观察者实例“Person”
帐户。 Person
发送一个addObserver:forKeyPath:options:context:
消息给Account
,每次观察到的关键路径一次,命名为观察者。
为了从Account接收更改通知,Person实现了所有观察者所需的observeValueForKeyPath:ofObject:change:context:
方法。 任何一个已注册的键值路径发生变化的情况下,该Account
将会发送消息给Person
。 然后,Person
可以根据更改通知采取适当的措施。
最后,当它不再需要通知,并且至少在它被释放之前,Person
实例必须通过将消息removeObserver:forKeyPath
发送到Account
来取消注册。
注册键值观察描述了键值观察通知的注册,接收和取消注册的完整生命周期。KVO的主要优点是,您不必在每次属性更改时实施自己的方案来发送通知。 其明确的基础架构具有框架级支持,使其易于采用 - 通常您不必为项目添加任何代码。 此外,基础架构已经是全功能的,这使得轻松支持单个属性的多个观察者以及依赖值。
与使用NSNotificationCenter
的通知不同,不存在为所有观察者提供更改通知的中心对象。 相反,当进行更改时,通知将直接发送到观察对象。 NSObject提供了这个键值观察的基础实现,你很少需要重写这些方法。
键值观察是一种机制,可以在另一个对象的属性更改时直接通知对象。 关键值观察(或KVO)可以是应用程序凝聚力的重要因素。 它是根据模型 - 视图 - 控制器设计模式设计的应用程序中的对象之间的通信模式。 例如,您可以使用它来将模型对象的状态与视图和控制器层中的对象进行同步。 通常情况下,控制器对象会观察模型对象,视图对象会观察控制器对象或模型对象。
使用KVO的要求是对象必须能支持KVC机制——所有NSObject的子类都支持这个机制。
虽然UIKit框架的类通常不支持KVO,但您仍然可以在应用程序的自定义对象中实现它,包括自定义视图。下图就是一种KVO的原理示意图。
使用KVO,一个对象可以观察到另一个对象的任何属性,包括简单属性,一对一关系以及多对多关系。 一个对象可以找出属性的当前值和先前值。 许多关系的观察者不仅被告知改变的类型,而且被告知哪些对象涉及变化。
作为通知机制,键值观察与NSNotification
和NSNotificationCenter
课程提供的机制相似,但也有显着差异。 不是将通知广播到已注册为观察者的所有对象的中心对象,KVO通知会在发生属性值更改时直接进行观察对象。
再看一部分开发文档。
Automatic key-value observing is implemented using a technique called isa-swizzling... When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class ..
翻译过来的主要意思就是:在我们对某个对象完成监听的注册后,编译器会修改监听对象的isa指针,让这个指针指向一个新生成的中间类。
这里说明一下isa
这个指针, isa是一个指向Class
类指针(专业术语是指向元类,pointer to the metaclass
),用来指向类的类型,我们可以通过object_getClass
方法来获取这个值;正常来说,class方法内部的实现就是获取这个isa指针代表的元类(metaclass
),但在kvo机制中苹果注册监听对象后 通过objc_allocateClassPair
动态重新创建了一个新类和元类。
KVO的实现
根类NSObject提供了一个基本的键值观察实现,您很少需要重写。 因此,所有Cocoa对象本身就具有关键价值观察能力。 要接收属性的KVO通知,您必须执行以下操作:
对于你想观察的属性,您必须确保被观察的类是键值遵守。KVO合规性要求观察对象的类别也符合KVC,并且允许属性的自动观察者通知或实现对属性的手动键值观察。
添加一个观察者的值可以改变的对象。 您可以通过调用
addObserver:forKeyPath:options:context :
来执行此操作。 观察者只是您的应用程序中的另一个对象。在观察对象中,实现方法
observeValueForKeyPath:ofObject:change:context:
。 当观察到的对象的属性的值发生变化时,调用此方法。
KVO是绑定的一部分(OS X)
Cocoa绑定是一种OS X技术,它允许您在模型中保留值并将应用程序的图层同步,而无需编写大量“胶合代码”。通过Interface Builder
检查器,您可以在视图的属性和一条数据之间建立一个介于中间的连接,“绑定”它们,使得一个变化反映在另一个中。 KVO以及键值编码和键值绑定是可可绑定功能的技术。
后记
未完,待续~~~