编写键值观察分为三个部分:
1.注册成为观察者
2.观察者定义KVO的回调
3.移除观察者
#import <Foundation/Foundation.h>
@interface Student : NSObject
//创建学生作为被观察者的对象
@property(copy,nonatomic)NSString *name;
@property(assign,nonatomic)NSUInteger age;
@end
#import "Student.h"
@implementation Student
-(NSString *)description
{
return [NSString stringWithFormat:@"My name is %@,I am %lu year old",self.name,self.age];
}
@end
#import <Foundation/Foundation.h>
#import "Student.h"
@interface StudentObserver : NSObject
@property(retain,nonatomic)Student *student;
//创建观察者
-(id)initWithStudent:(Student *)newStudent;
@end
#import "StudentObserver.h"
@implementation StudentObserver
-(id)initWithStudent:(Student *)newStudent
{
if (self = [super init])
{
self.student = newStudent;
//注册成为观察者
[self.student addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
[self.student addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
return self;
}
//重写观察者的回调方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"name"])
{
NSString *oldName = [change objectForKey:NSKeyValueChangeOldKey];
NSString *newName = [change objectForKey:NSKeyValueChangeNewKey];
NSLog(@"键路径%@对应的值发生改变,从%@变成%@",keyPath,oldName,newName);
}
else if ([keyPath isEqualToString:@"age"])
{
NSNumber *oldAge = [change objectForKey:NSKeyValueChangeOldKey];
NSNumber *newAge = [change objectForKey:NSKeyValueChangeNewKey];
NSLog(@"键路径%@对应的值发生改变,从%@变成%@",keyPath,oldAge,newAge);
}
}
-(void)dealloc
{
//移除观察者
[self.student removeObserver:self forKeyPath:@"_name"];
[self.student removeObserver:self forKeyPath:@"_age"];
}
@end
#import "ViewController.h"
#import "Student.h"
#import "StudentObserver.h"
@interface ViewController ()
{
Student *student;
StudentObserver *studentObserver; //把观察者变成全局变量
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
student = [Student new];
studentObserver = [[StudentObserver alloc]initWithStudent:student];
[student setValue:@"hejin" forKey:@"name"];
[student setValue:[NSNumber numberWithInt:18] forKey:@"age"];
[student setValue:@"hejin2" forKey:@"name"];
[student setValue:[NSNumber numberWithInt:25] forKey:@"age"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end