KVO 即Key-Value Observing 键-值观察的缩写,简单的说就是通过键来观察一个对象属性值的变化。当这个被观察的属性发生变化时,观察者就会收到通知(观察者可以是这个对象本身,也可以是其他对象)。
下面来模拟KVO的实现过程:
创建一个People类,其有俩个属性name,sex
-----------------------People.h文件中----------------------------
#import <Foundation/Foundation.h>
@interface Person : NSObject
- (void)changeName; //写一个改变name值的方法
@property (nonatomic ,copy)NSString *name; //以name为例,来观察name值的变化
@property (nonatomic ,copy)NSString *sex;
@end
-----------------------People.m文件中----------------------------
#import "Person.h"
@implementation Person
@synthesize name,sex;
- (void)changeName
{
self.name = @"我被监视了";
}
@end
创建一个观察者PeopleObserve类,在这个类中我们来观察People类的name值的变化,使用其实很简单,实现一个方法即可
-----------------------PeopleObserve.m文件中----------------------------
#import "PeopleObserve.h"
@implementation PeopleObserve
//监视person中属性name的变化, change这个参数就是保存name改变前后的值的一个字典。
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"name"]) {
//使用[change objectForKey:NSKeyValueChangeOldKey],有时会不提示objectForKey:敲出来即可。
NSLog(@"changHappen 旧的值:%@ 新的值:%@",[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey]);
}
}
@end
---------下面在AppDelegate入口类中模拟一下name值的改变时PeopleObserve类中的输出------------
#import "AppDelegate.h"
#import "Person.h"
#import "PeopleObserve.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
//被监视的对象
Person *p = [[Person alloc] init];
p.name = @"被观察者"; //先给name赋个值,以便观察
PeopleObserve *po = [[PersonMonitor alloc] init];
//p为被观察者 ,po 为观察者,观察到变化时,调用方法
[p addObserver:pm forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
[p changeName];
//下面两种方式都可改变name的值,KVC的赋值方式
// [p setValue:@"我又被观察了" forKeyPath:@"name"];
// [p setValue:@"我再次被观察了" forKey:@"name"];
return YES;
}
---------------输出结果-----------------