1.创建被观察的对象
PersonInfo.h
#import <Foundation/Foundation.h>
@interface PersonInfo : NSObject
@property (nonatomic, assign) NSInteger age;
+ (instancetype)create;
@end
PersonInfo.m
#import "PersonInfo.h"
@implementation PersonInfo
+ (instancetype)create {
PersonInfo *personInfo = [PersonInfo new];
return personInfo;
}
@end
2.观察者为ViewController的实例对象, 被观察的是PersonInfo的age属性
ViewController.h
#import <UIKit/UIKit.h>
#import "PersonInfo.h"
@interface ViewController : UIViewController
@property (nonatomic, strong) PersonInfo *personInfo;
@end
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
#pragma mark - ViewController LifeCycle
- (void)viewDidLoad {
[super viewDidLoad];
[self initPersonInfo]; //创建PersonInfo
[self addObserverForPersonAge]; //添加观察者
}
- (void)dealloc {
[self removeObserverForPersonAge]; //移除观察者
}
#pragma mark - IBAction Methods
- (IBAction)changeAgeButtonClicked:(id)sender {
self.personInfo.age = arc4random()%200; //点击按钮, 随机产生一个年龄
}
#pragma mark - Observe Methods
/*
*KeyPath: 被观察属性的字段名称
*context: 联系上下文, 可用来传值
*options: 被观察属性的旧值或新值得设置项 (4个), 不同的组合, 可获取不同维度的值
*NSKeyValueObservingOptionOld 只可获取旧值
*NSKeyValueObservingOptionNew 只可获取新值
*NSKeyValueObservingOptionInitial 注册即会调用一次, 只可获取新值 (需配合: NSKeyValueObservingOptionNew)
*NSKeyValueObservingOptionPrior 调用两次, 在值改变之前和值改变之后
*/
- (void)addObserverForPersonAge {
[self.personInfo addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
}
- (void)removeObserverForPersonAge {
[self.personInfo removeObserver:self forKeyPath:@"age" context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
NSInteger oldAge = [[change objectForKey:NSKeyValueChangeOldKey] integerValue];
NSLog(@"Old age: %ld", (long)oldAge);
NSInteger newAge = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
NSLog(@"New age: %ld", (long)newAge);
}
#pragma mark - Private Methods
- (void)initPersonInfo {
self.personInfo = [PersonInfo create];
self.personInfo.age = 6;
}
@end