注册观察者:
(void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
- observer:观察者,监听属性变化的对象。 该对象必须实现observeValueForKeyPath:ofObject:change:context: 方法。
- keyPath:要观察的属性名称。要和属性声明的名称一致。
- options:对KVO机制进行配置,修改KVO通知的时机以及通知的内容
- context: 传入任意类型的对象,在"接收消息回调"的代码中可以接收到这个对象,是KVO中的一种传值方式。
四个options:
enum {
// 提供属性的新值
NSKeyValueObservingOptionNew = 0x01,
// 提供属性的旧值
NSKeyValueObservingOptionOld = 0x02,
// 如果指定,则在添加观察者的时候立即发送一个通知给观察者,
// 并且是在注册观察者方法返回之前
NSKeyValueObservingOptionInitial = 0x04,
// 如果指定,则在每次修改属性时,会在修改通知被发送之前预先发送一条通知给观察者,
// 这与-willChangeValueForKey:被触发的时间是相对应的。
// 这样,在每次修改属性时,实际上是会发送两条通知。
NSKeyValueObservingOptionPrior = 0x08
};
typedef NSUInteger NSKeyValueObservingOptions;
接受通知:
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;
取消注册:
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
举例:
有两个视图控制器,点按第一个视图的skip按钮跳转到第二个界面,第二个界面有一个一个keyTextField和keyString属性,更改keyTextField的text,再把text赋给keyString。返回第一个页面,labelChanging的文字改变。
实现:
在第一个视图控制器中的skip按钮事件里:
- (void)pressSkipButton {
_secondPage = [[SecondViewController alloc] init];
[_secondPage addObserver:self forKeyPath:@"keyString" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
[self.navigationController pushViewController:_secondPage animated:YES];
}
再添加接收通知方法:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
NSLog(@"%@",keyPath);
if ([keyPath isEqualToString:@"keyString"] && object == _secondPage) {
_labelChanging.text = [change valueForKey:@"new"];
//change的使用:上文注册时,枚举为2个,因此可以提取change字典中的新、旧值的这两个方法
NSLog( @"old:%@ new:%@",[change valueForKey: @"old"], [change valueForKey: @"new"]);
}
}
最后:
- (void)dealloc {
[_secondPage removeObserver:self forKeyPath:@"keyString"];
}
在第二个视图控制器中(菜鸡偷懒就写在viewWillDisappear里了):
- (void)viewWillDisappear:(BOOL)animated {
self.keyString = _keyTextField.text;
}
这样就可以实现功能(效果图):
输出结果: