KVO传值

注册观察者:

(void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
  1. observer:观察者,监听属性变化的对象。 该对象必须实现observeValueForKeyPath:ofObject:change:context: 方法。
  2. keyPath:要观察的属性名称。要和属性声明的名称一致。
  3. options:对KVO机制进行配置,修改KVO通知的时机以及通知的内容
  4. 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;
}

这样就可以实现功能(效果图):
KVO传值
KVO传值
输出结果:
KVO传值

上一篇:element-ui的change方法传递参数


下一篇:部署minio