KVO(键值监听)全称 Key Value Observing。使用KVO可以实现视图组件和数据模型的分离,视图作为监听器,当模型的属性值发生变化后,监听器可以做相应的处理。KVO的方法由NSKeyValueObserving协议提供,同样NSObject已经实现了该协议,因此几乎所有的对象都可以使用KVO。
使用KVO操作常用的方法如下:
注册制定路径的监听器: addObserver: forKeyPath: option: context:
删除制定路径的监听器:removeObserver: forKeyPath:
触发监听时的方法:observeValueForKeyPath: ofObject: change: context:
引入的三方头文件:
#import "ReactiveObjC.h" #import "MJExtension.h"
声明的属性:
@interface ViewController () @property(nonatomic, strong) UITextField *textField; @property(nonatomic, strong) UILabel *lableRetValue; @end
实现方法:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.view.backgroundColor = [UIColor whiteColor]; self.person = [[Person alloc] init]; [self.person addObserver:self forKeyPath:@"str" options:NSKeyValueObservingOptionNew context:nil]; [self.textField.rac_textSignal subscribeNext:^(NSString * _Nullable x) { [self.person setValue:x forKey:@"str"]; }]; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ if ([keyPath isEqualToString:@"str"]) { self.lableRetValue.text = [change valueForKey:@"new"]; } } -(UILabel *)lableRetValue{ if (!_lableRetValue) { _lableRetValue = [UILabel new]; _lableRetValue.layer.borderColor = [UIColor redColor].CGColor; _lableRetValue.layer.borderWidth = 1.f; _lableRetValue.textAlignment = NSTextAlignmentCenter; [self.view addSubview:_lableRetValue]; [_lableRetValue mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.view).offset(100); make.centerX.equalTo(self.view); make.width.equalTo(self.view).multipliedBy(0.6); make.height.offset(50); }]; } return _lableRetValue; } -(UITextField *)textField{ if (!_textField) { _textField = [UITextField new]; _textField.placeholder = @"请输入内容"; _textField.keyboardType = UIKeyboardTypeNumberPad; _textField.textAlignment = NSTextAlignmentCenter; _textField.backgroundColor = [UIColor grayColor]; [self.view addSubview:_textField]; [_textField mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.lableRetValue.mas_bottom).offset(40); make.centerX.equalTo(self.view); make.width.equalTo(self.view).multipliedBy(0.7); make.height.offset(50); }]; } return _textField; }