iOS的消息传递方式-4.KVO

1.1 KVO的定义

KVO(Key-Value Observing),俗称键值监听。它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。

1.2 KVO的使用

KVO的定义KVO是“观察者”设计模式的一种应用,利用它可以很容易实现视图组件和数据模型的分离,当数据模型的属性值改变之后作为监听器的视图组件就会被激发,激发时就会回调监听器自身。这种模式有利于两个类间的解耦合,尤其是对于业务逻辑与视图控制 这两个功能的解耦合。和KVC类似,在ObjC中要实现KVO则必须实现NSKeyValueObServing协议,但不用担心,因为NSObject已经实现了该协议,因此几乎所有的ObjC对象都可以使用KVO.

1.3KVO常用的方法

1>注册指定Key路径的监听器

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
相关参数:
observer:观察者,也就是KVO通知的订阅者。订阅着必须实现
observeValueForKeyPath:ofObject:change:context:方法
keyPath:描述将要观察的属性,相对于被观察者。 
options:KVO的一些属性配置;有四个选项。 
   options所包括的内容:
   NSKeyValueObservingOptionNew:  change字典包括改变后的值 
   NSKeyValueObservingOptionOld:   change字典包括改变前的值 
   NSKeyValueObservingOptionInitial:注册后立刻触发KVO通知 
   NSKeyValueObservingOptionPrior:值改变前是否也要通知(这个key决定了是否在改变前改变后通知两次)
context: 上下文,这个会传递到订阅着的函数中,用来区分消息,所以应当是不同的。
注意:不要忘记解除注册,否则会导致资源泄露

2>删除指定Key路径的监听器:

  - (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath
  - (void)removeObserver:(NSObject *)observer     forKeyPath:(NSString *)keyPath  context:(void *)context

3>回调监听

  - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
  keyPath:被监听的keyPath , 用来区分不同的KVO监听。 
  object: 被观察修改后的对象(可以通过object获得修改后的值) 
  change:保存信息改变的字典(可能有旧的值,新的值等) 
  context:上下文,用来区分不同的KVO监听
KVO的使用步骤也比较简单
 1>注册,指定被观察者的属性
 2> 实现回调方法
 3>移除观察
1.4 KVO的使用场景
@interface StockData : NSObject {  
    NSString * stockName;  
    float price;  
}  
@end  
@implementation StockData  
@end
- (void)viewDidLoad  
{  
    [super viewDidLoad];  
  
    stockForKVO = [[StockData alloc] init];  
    [stockForKVO setValue:@"searph" forKey:@"stockName"];  
    [stockForKVO setValue:@"10.0" forKey:@"price"];      
    [stockForKVO addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];  
  
    myLabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 30 )];  
    myLabel.textColor = [UIColor redColor];  
    myLabel.text = [stockForKVO valueForKey:@"price"];  
    [self.view addSubview:myLabel];  
     
    UIButton * b = [UIButton buttonWithType:UIButtonTypeRoundedRect];  
    b.frame = CGRectMake(0, 0, 100, 30);  
    [b addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];  
    [self.view addSubview:b];  
  
}
-(void) buttonAction  
{  
    [stockForKVO setValue:@"20.0" forKey:@"price"];  
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context  
{  
    if([keyPath isEqualToString:@"price"])  
    {  
        myLabel.text = [stockForKVO valueForKey:@"price"];  
    }  
}
- (void)dealloc  
{  
    [stockForKVO removeObserver:self forKeyPath:@"price"];  
}

你可能感兴趣的:(iOS的消息传递方式-4.KVO)