iOS对KVO的理解和错误分析

起初设想在控制器上面新建一个UITextfield,通过KVO监听输入text的变化。将变化后的值显示在控制器的label上面。代码如下。

```

[self.stockTextFieldaddObserver:selfforKeyPath:@"text"options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOldcontext:nil];

-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context{

if([keyPathisEqualToString:@"text"] &&object ==self.stockTextField)

{self.valueLabel.text= [changevalueForKey:@"new"];}

}

```

##希望在控制器上输入改变的时候能顺利的看到跳到observeValueForKeyPath的方法中,结果是KVO无法进行观察。分析原因:通过换一种方式对text的值做改变,增加一个按钮,在每次点击按钮之前对text的值做改变。

```

- (IBAction)btnClick:(UIButton*)sender {

self.stockTextField.text= [NSStringstringWithFormat:@"%ld",_num++];;

}

```

在这种情况下,会跳到observeValueForKeyPath方法中。至此,查看KVO的原理,即可初步怀疑原因,textfield输入的话是直接_text = @"123456"的赋值方式,而没有调用-(void)setText:(NSString *)text方法,所以发送通知进而进入observeValueForKeyPath:。直接观察者观察的是属性,只有遵循 KVO 变更属性值的方式才会执行KVO的回调方法,例如是否执行了setter方法、或者是否使用了KVC赋值。如果赋值没有通过setter方法或者KVC,而是直接修改属性对应的成员变量,例如:仅调用_text = @"123",这时是不会触发kvo机制,更加不会调用回调方法的。所以使用KVO机制的前提是遵循 KVO 的属性设置方式来变更属性值。

![](http://i2.muimg.com/567571/aa0f46f4170ff4ed.png)

![](http://i1.piimg.com/567571/d3d5a8e8fed62a08.gif)

你可能感兴趣的:(iOS对KVO的理解和错误分析)