KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。
一自动键值观察
1.注册,指定被观察者的属性
2.实现回调方法
3.移除观察
1步的方法代码
[_webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];//context一些其他的需要传递给观察者的上下文信息
2步的实现回调
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
if (object == _webView.scrollView && [keyPath isEqualToString:@"contentSize"]) {
float height = [[_webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];
CGRect newFrame = _webView.frame;
newFrame.size.height = height;
_webView.frame = newFrame;
_sumHeight = height;
_tableHeaderBackgroundView.frame = CGRectMake(0, 0, ScreenWidth, height);
_openClasTableView.tableHeaderView = _tableHeaderBackgroundView;
[_openClasTableView reloadData];
}
}
3第三步的代码移除观察
-(void)dealloc{
[_webView.scrollView removeObserver:self forKeyPath:@"contentSize"];
}
二手动键值观察
在NSKeyValueObserving.h 文件里面的方法
- (void)willChangeValueForKey:(NSString *)key;
- (void)didChangeValueForKey:(NSString *)key;
需要重写set方法
- (void) setAge:(int)theAge
{
[self willChangeValueForKey:@"age"];
age = theAge;
[self didChangeValueForKey:@"age"];
}
+ (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key {
if ([key isEqualToString:@"age"]) {
return NO;
}
return [super automaticallyNotifiesObserversForKey:key];
}
首先,需要手动实现属性的 setter 方法,并在设置操作的前后分别调用 willChangeValueForKey: 和 didChangeValueForKey方法,这两个方法用于通知系统该 key 的属性值即将和已经变更了;
其次,要实现类方法 automaticallyNotifiesObserversForKey,并在其中设置对该 key 不自动发送通知(返回 NO 即可)。这里要注意,对其它非手动实现的 key,要转交给 super 来处理。