KVO
KVO的意思是Key Value Observering 键值观察
使得对象可以观察其他对象的属性 做出响应
非常适用的一个场景是用于更新UI
通常的更新UI的方式是 model通知控制器 需要更新某个属性值
这样的做法需要每个属性都写接口来更新
而且会导致代码非常冗余 因为控制器和model需要通过指针互相引用
而KVO可以让控制器知道模型的属性变化 从而直接更新UI
示例
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) UITextView *textView;
@property (nonatomic) int num;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.num = 0;
self.textView = [[UITextView alloc] initWithFrame:CGRectMake(100, 100, 200, 50) textContainer:nil];
[self.textView setText:[NSString stringWithFormat:@"num %d", self.num]];
[self.view addSubview:self.textView];
[self addObserver:self forKeyPath:@"num" options:NSKeyValueObservingOptionNew context:nil]; //注册KVO观察属性 属性名直接对应变量名
//observer是self是因为num是这个类的属性 如果num在另一个类里 就写那个类的对象
self.num++; //修改属性值 触发KVO回调
}
- (void)dealloc
{
[self removeObserver:self forKeyPath:@"num"]; //移除KVO
}
- (void)updateTextView
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.textView setText:[NSString stringWithFormat:@"num %d", self.num]]; //更新UI
});
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
// KVO被触发 且属性是num
if ([keyPath isEqualToString:@"num"]) {
[self updateTextView];
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
@end
KVO的实现原理
https://www.jianshu.com/p/91c41292b5b9