摘要
KVO的是Key Value Observe的缩写,中文是键值观察。这是一个典型的观察者模式,观察者在键值改变时会得到通知。iOS中有个Notification的机制,也可以获得通知,但这个机制需要有个Center,相比之下KVO更加简洁而直接。
KVO简介
KVO
的是Key Value Observe
的缩写,中文是键值观察。这是一个典型的观察者模式,观察者在键值改变时会得到通知。iOS中有个Notification
的机制,也可以获得通知,但这个机制需要有个Center
,相比之下KVO
更加简洁而直接。
KVO的使用也很简单,就是简单的3步。
1.注册需要观察的对象的属性addObserver:forKeyPath:options:context:
2.实现observeValueForKeyPath:ofObject:change:context:方法,这个方法当观察的属性变化时会自动调用
3.取消注册观察removeObserver:forKeyPath:context:
测试代码如下:
被观察对象:Student类
//
// Student.h
// KVO练习
//
// Created by on 15-3-15.
// Copyright (c) 2015年 apple. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Student : NSObject {
NSString *name;
}
@end
//
// Student.m
// KVO练习
//
// Created by on 15-3-15.
// Copyright (c) 2015年 apple. All rights reserved.
//
#import "Student.h"
@implementation Student
@end
监听类:Teacher
//
// Teacher.h
// KVO练习
//
// Created by on 15-3-15.
// Copyright (c) 2015年 apple. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Student.h"
@interface Teacher : NSObject
{
Student *st;
}
- (id)init:(Student *)student;
@end
//
// Teacher.m
// KVO练习
//
// Created by on 15-3-15.
// Copyright (c) 2015年 apple. All rights reserved.
//
#import "Teacher.h"
@implementation Teacher
- (id)init:(Student *)student {
if (self = [super init]) {
st = student;
// 设置观察者和被观察属性
// 用传入的形参来调用注册函数,参数Observer是监听者,KeyPath是被监听者的某个受关注的属性或实例变量,options是希望得到的变化的值,即新值旧值,
// context是其他附加信息
[st addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
}
return self;
}
// 下面函数是自动调用的,只要你所监听对象的属性或者实例变量发生变化,就自动调用该函数,执行相应操作
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
NSLog(@"Teacher观察的属性是:%@",keyPath);
NSLog(@"Student被修改前的姓名是:%@", [change objectForKey:NSKeyValueChangeOldKey]);
NSLog(@"Student被修改后的姓名是:%@",[change objectForKey:NSKeyValueChangeNewKey]);
}
// 移除监听者,开启ARC也要加上这一句
// 但是开启ARC在最后可以不用写[super dealloc]
- (void)dealloc {
[st removeObserver:self forKeyPath:@"name" context:nil];
NSLog(@"销毁观察者");
}
@end
监听测试:
//
// main.m
// KVO练习
//
// Created by on 15-3-15.
// Copyright (c) 2015年 apple. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Student.h"
#import "Teacher.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *stu = [[Student alloc] init];
// 设置初始值
[stu setValue:@"jack" forKey:@"name"];
NSLog(@"Student的name属性的初始值:%@", [stu valueForKey:@"name"]);
Teacher *teacher = [[Teacher alloc] init:stu];
// 改变值
[stu setValue:@"tom" forKey:@"name"];
}
return 0;
}
打印结果:
2015-03-15 23:05:00.121 KVO练习[1570:303] Student的name属性的初始值:jack
2015-03-15 23:05:00.123 KVO练习[1570:303] Teacher观察的属性是:name
2015-03-15 23:05:00.123 KVO练习[1570:303] Student被修改前的姓名是:jack
2015-03-15 23:05:00.123 KVO练习[1570:303] Student被修改后的姓名是:tom
2015-03-15 23:05:00.124 KVO练习[1570:303] 销毁观察者