1.新建项目,UI界面设计如下:第一个是便签,用于显示num数值,关联ViewController并命名为:label; 第二个是按钮,用于改变num的数值,关联ViewController并命名为:changeNum。
2.模型创建【新建一个File,选择Cocoa Touch Class,命名为“myKVO”,记得选择Subclass of “NSObject”.】代码如下:(myKVO.h):@interface myKVO : NSObject@property (nonatomic,assign)int num; //属性设置为int类型的num@end(myKVO.m):复制代码#import "myKVO.h"@implementation myKVO@synthesize num;@end复制代码
3.在ViewController中监听并响应属性改变。(ViewController.h):复制代码#import@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *label;//便签label
- (IBAction)changeNum:(UIButton *)sender; //按钮事件
@end复制代码 (ViewController.m):复制代码
#import "ViewController.h"#import "myKVO.h"
@interface ViewController ()@property (nonatomic,strong)myKVO *myKVO;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.myKVO = [[myKVO alloc]init];
/*1.注册对象myKVO为被观察者: option中, NSKeyValueObservingOptionOld 以字典的形式提供 “初始对象数据”; NSKeyValueObservingOptionNew 以字典的形式提供 “更新后新的数据”; */ [self.myKVO addObserver:self forKeyPath:@"num" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];}/* 2.只要object的keyPath属性发生变化,就会调用此回调方法,进行相应的处理:UI更新:*/
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void *)context
{
if([keyPath isEqualToString:@"num"] && object == self.myKVO)
{
// 响应变化处理:UI更新(label文本改变)
self.label.text = [NSString stringWithFormat:@"当前的num值为:%@",[change valueForKey:@"new"]];
//change的使用:上文注册时,枚举为2个,因此可以提取change字典中的新、旧值的这两个方法
NSLog(@"\noldnum:%@ newnum:%@",[change valueForKey:@"old"],[change valueForKey:@"new"]);
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
/* 3.移除KVO */
[self removeObserver:self forKeyPath:@"num" context:nil];
}
//按钮事件
- (IBAction)changeNum:(UIButton *)sender {
//按一次,使num的值+1
self.myKVO.num = self.myKVO.num + 1;
}
@end
复制代码
调试:便签label初始化没有数值,当每次点击按钮后,label记录的num随之增加,表明按钮使属性num增加的同时,KVO机制发送通知,并调用observeValueForKeyPath:方法使UI更新。