Key-value observing is a mechanism that enables an object to be notified directly when a property of another object changes. Key-value observing (or KVO) can be an important factor in the cohesiveness of an application. It is a mode of communication between objects in applications designed in conformance with the Model-View-Controller design pattern. For example, you can use it to synchronize the state of model objects with objects in the view and controller layers. Typically, controller objects observe model objects, and views observe controller objects or model objects.
键值观察是一种机制,当另一个对象的属性发生变化时,可以直接通知对象。键值观察(或KVO)可能是应用程序内聚性的一个重要因素。它是应用程序中按照模型-视图-控制器设计模式设计的对象之间的一种通信模式。例如,您可以使用它将模型对象的状态与视图层和控制器层中的对象同步。通常,控制器对象观察模型对象,视图观察控制器对象或模型对象。
KVO.png
KVO.png
线程安全问题: 在B线程setValue, 在A线程加观察者 (eg:子线程更新Data , 主线程更新UI)
Implementing KVO
The root class, [NSObject](https://developer.apple.com/library/archive/documentation/LegacyTechnologies/WebObjects/WebObjects_3.5/Reference/Frameworks/ObjC/Foundation/Classes/NSObject/Description.html#//apple_ref/occ/cl/NSObject)
, provides a base implementation of key-value observing that you should rarely need to override. Thus all Cocoa objects are inherently capable of key-value observing. To receive KVO notifications for a property, you must do the following things:
-
You must ensure that the observed class is key-value observing compliant for the property that you want to observe.
KVO compliance requires the class of the observed object to also be KVC compliant and to either allow automatic observer notifications for the property or implement manual key-value observing for the property.
-
Add an observer of the object whose value can change. You do this by calling
[addObserver:forKeyPath:options:context:](https://developer.apple.com/documentation/objectivec/nsobject/1412787-addobserver)
. The observer is just another object in your application. -
In the observer object, implement the method
[observeValueForKeyPath:ofObject:change:context:](https://developer.apple.com/documentation/objectivec/nsobject/1416553-observevalueforkeypath)
. This method is called when the value of the observed object’s property changes.
三部曲:
- (void)willMoveToSuperview:(UIView *)newSuperview
{
if (newSuperview == nil)
{
// 移除
[self.superview removeObserver:self forKeyPath:@"contentOffset"];
}
else
{
// 添加
[newSuperview addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
}
[super willMoveToSuperview:newSuperview];
}
// 收到通知
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
CGFloat offset = [[change objectForKey:@"new"] CGPointValue].y;
CGFloat oldOffset = [[change objectForKey:@"old"] CGPointValue].y;
// ....
}
网友评论