在iOS开发的过程中,iOS应用通常会把应用程序组建分开成数据模型组件和视图组件
其中数据模型组件负责维护应用程序的状态数据
而视图组件则负责显示数据模型组件内部的状态数据
对于上面介绍的设计结构,如果程序存在的需求是:
在数据模型组件的状态数据发生改变的时候,
希望视图组件能动态的更新自己,及时的显示数据模型更新后的数据。
NSKeyValueObserving协议提供支持 ,该协议包含了一下常用方法用于住注册监听器addObserver:forlKeyPath:options:context::注册-个监听器用于监听指定的key 路径。removeObserver:forkeyPath::为key路径删除指定的监听器removeObserver:forKeyPathicontext:为key 路径删除指定的监听器。只是多了—个 contextobserveValueForKeyPath:ofObject:change:context
由此可见,作为监听器的视图组件需要重写observeValue ForkeyPath:ofObject:change: context方法,重写该方法时就可以得到最新改的数据,从而使用最新的数据来更新视图组件的显示
observe ValueForKeyPath:ofObject:change:context:方法#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Dog : NSObject
@property (nonatomic, assign) int high;
@end
NS_ASSUME_NONNULL_END
ViewController.m#import <UIKit/UIKit.h>
#import "Dog.h"
@interface ViewController : UIViewController
@property (nonatomic, strong) UILabel* label;
@property (nonatomic, strong) UIButton* button;
@property (nonatomic, strong) Dog* lyt;
ViewContrller.h#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
_label = [[UILabel alloc] init];
_label.frame = CGRectMake(100, 300, 200, 50);
_label.font = [UIFont systemFontOfSize:20];
[self.view addSubview:_label];
// 初始化点击button
_button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[_button setTitle:@"长高" forState:UIControlStateNormal];
[_button addTarget:self action:@selector(pressButton:) forControlEvents:UIControlEventTouchUpInside];
_button.frame = CGRectMake(15, 400, 100, 40);
[self.view addSubview:_button];
// 设置监听
_lyt = [[Dog alloc] init];
[_lyt addObserver:self forKeyPath:@"high" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionNew context:nil];
}
// 点击button触发监听
- (void)pressButton: (UIButton*)button {
static int high = 0;
_lyt.high = high++;
}
// 监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
NSString* str = [NSString stringWithFormat:@"我的身高%d", _lyt.high];
_label.text = str;
NSLog(@" new high %@", [change valueForKey:@"new"]);
}
// 移除监听
- (void)dealloc {
[_lyt removeObserver:self forKeyPath:@"high"];
}
@end
点击一下button 我们设置的监听事件就触发一次

记得最后加上取消监听函数(在不使用的时候移除监听)
// 移除监听
- (void)dealloc {
[_lyt removeObserver:self forKeyPath:@"high"];
}