Key-value observing provides a mechanism that allows objects to be notified of changes to specific properties of other objects.A controller object typically observes properties of model objects, and a view object observes properties of model objects through a controller.
class 必须首先遵从 NSKeyValueCoding 、然后是 NSKeyValueObserving
Registering for Key-Value Observing
Receiving Notification of a Change
Removing an Object as an Observer
You must perform the following steps to enable an object to receive key-value observing notifications for a KVO-compliant property:
//Register the observer with the observed object
//passing itself as the observer and the key path of the property to be observed.
//The observer additionally specifies an options parameter and a context pointer to manage aspects of the notifications.
//A safer and more extensible approach is to use the context to ensure notifications you receive are destined for your observer and not a superclass.
- addObserver:forKeyPath:options:context:
//accept change notification messages
- observeValueForKeyPath:ofObject:change:context:
//Unregister the observer,At a minimum, invoke this method before the observer is released from memory.
- removeObserver:forKeyPath:
注意:The key-value observing addObserver:forKeyPath:options:context:method does not maintain strong references to the observing object, the observed objects, or the context.
注册监听器:
- addObserver:forKeyPath:options:context: 注册一个监听器用于监听指定Key路径
- removeObserver:forKeyPath: 为指定Key路径删除指定的监听器
- removeObserver:forKeyPath:context: 为指定Key路径删除指定的监听器,只是多了一个context参数。
监听器开始观察:
- observeValueForKeyPath:ofObject:change:context:
- (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
返回yes(默认返回YES),不用调用willChangeValueForKey
返回no,在改变被观察的属性值时,需要自己调用willChangeValueForKey 或 didChangeValueForKey 方法
如果不使用存取器,需要在每次修改属性的实例变量时调用 willChangeValueForKey: 和 调用 didChangeValueForKey:
Key-Value Observing Implementation Details
Automatic key-value observing is implemented using a technique called isa-swizzling.
kvo实现原理图The isa pointer, as the name suggests, points to the object's class which maintains a dispatch table. This dispatch table essentially contains pointers to the methods the class implements, among other data.
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. As a result the value of the isa pointer does not necessarily reflect the actual class of the instance.
You should never rely on the isa pointer to determine class membership. Instead, you should use the class method to determine the class of an object instance.
网友评论