Key-Value Observing提供了一种机制,当指定对象的属性发生变化时,允许对象接受到通知的机制。通俗的说,就是每次指定的被观察对象的属性发生改变时,KVO都会自动的通知相应的观察者。
(1)首先,构思一下实现KVO是否必要。一个对象,当另一个对象的属性发生变化时,需要被通知到 比如PersonObject要观察BankObject的属性accountBalance的变化
(2)PersonObject必须发送一个“addObserver:forKeyPath:options:context:”消息,注册成为BankObject的属性accountBalance的观察者(说 明:“addObserver:forKeyPath:options:context:”方法在指定对象实例之间建立了一个连接。注意,这个连接不是两 个类之间建立的,而是两个对象实例之间建立的。)
(3)为了能够响应消息,观察者必须实现“observeValueForKeyPath:ofObject:change:context:”方法。这个方法实现如何响应消息的变化。在这个方法里面,我们根据自己的实际情况,实现被观察者的属性发生变化时相应的逻辑
4)加入遵循kvo原则的话,当被观察者的属性发生变化时,方法“observeValueForKeyPath:ofObject:change:context:”或自动被调用。
KVO是如何工作的:(1)注册,指定被观察对象的属性,添加观察者
(2)实现回调方法
(3)移除观察者
事例代码:
建立一个Model
#import <Foundation/Foundation.h>
@interface BankObject : NSObject
{
float account;
}
@end
#import "BankObject.h"
@implementation BankObject
@end
#import <UIKit/UIKit.h>
#import "BankObject.h"
@interface ViewController : UIViewController
{
BankObject * bankAccount;
UILabel * _myLabel;
UIButton * _myButton;
}
@end
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
bankAccount = [[BankObject alloc] init];
[bankAccount setValue:@"10" forKey:@"account"];
[bankAccount addObserver:self forKeyPath:@"account" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
_myLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 200, 100)];
_myLabel.text = [NSString stringWithFormat:@"%@",[bankAccount valueForKey:@"account"]];
_myLabel.textColor = [UIColor whiteColor];
[self.view addSubview:_myLabel];
_myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
_myButton.frame = CGRectMake(200, 300, 100, 50);
_myButton.backgroundColor = [UIColor redColor];
[_myButton addTarget:self action:@selector(changeAccount) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_myButton];
}
- (void)changeAccount{
[bankAccount setValue:@"20" forKey:@"account"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"account"]) {
_myLabel.text = [NSString stringWithFormat:@"%@",[bankAccount valueForKey:@"account"]];
}
}
这样当我们点击button时,account的值改变,即bankAccount的属性发生了改变,观察者viewController接受到通知,执行observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context方法,label文本发生改变,由10变成20
参考链接:http://www.cnblogs.com/pengyingh/articles/2383629.html