1. 什么是KVO
1) KVO是基于键值和Notification通知。
2) 当指定的被观察的对象的属性被修改后,KVO自动通知相应的观察者。
2. 什么情况下用KVO
1) 通常适用于根据A类(数据类)的某个属性值变化,B(view类)中的某个属性(控件状态)做出相应变化。体现了MVC的思想
2) 比如用于用户界面交互,当多个View共同使用了同一个实体(数据类),当这个实体中的某个属性改变时,如果需要更新多个界面,KVO就能发挥作用了
3) 拷贝大文件的时候监听已拷贝的文件大小,该功能适合用于loading的时候用
3. KVO的使用步骤
1) 首先要注册监听,就是监听某个类里面属性的值的变化
[child addObserver:self forKeyPath:@"happyVal" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
2) 然后再该类中,重写该监听方法,输出属性的变化
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"%@",change);
}
4. KOV示例
Child.h
#import <Foundation/Foundation.h>
@interface Child : NSObject
@property(nonatomic,assign) NSInteger happyVal;
@end
Child.m
#import "Child.h"
@implementation Child
//加定时器,让它1s种变化一次,这种情况需要初始化父类的
-(id)init
{
self = [super init];
{
if (self != Nil)
self.happyVal = 100;
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
}
return self;
}
- (void) timerAction:(NSTimer *)timer
{
self.happyVal --; //让happyVal这个值递减
}
@end
Nurse.h
#import <Foundation/Foundation.h>
@class Child;
@interface Nurse : NSObject
@property(nonatomic,retain)Child* child;
-(id)initWithChild:(Child *)child;
@end
Nurse.m
#import "Nurse.h"
#import "Child.h"
@implementation Nurse
- (id)initWithChild:(Child *)child
{
self = [super init];
if (self != nil) {
self.child = child; //或者这样:_child = [child retain];
//使用KVO注册监听, forKeyPath:@"happyVal" 其中happyVal是表示属性的名称.addObserver:self,slef表示在当前对象注册一个方法
[child addObserver:self forKeyPath:@"happyVal" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
return self;
}
//这个方法与上面方法一一对应
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"%@",change);
}
main.m
#import <Foundation/Foundation.h>
#import "Child.h"
#import "Nurse.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Child *chlid = [[Child alloc]init];
Nurse *nurse = [[Nurse alloc] initWithChild:chlid];
//运行监听方法,以每一秒钟输出一个数值循环
/*output:
kind = 1;
new = 1;
old = 2;
*/
[[NSRunLoop currentRunLoop] run];
}
return 0;
}