Objective-C 「KVO键值观察」
2016-06-21 本文已影响555人
LuisX
Objective-C
- Key Value Observing(键-值-观察)
- 被观察者和观察者同时实现一个协议: NSKeyValueObserving
- 源于设计模式中的观察者模式。
- 指定被观察对象的属性被修改后,KVO就会自动通知相应的观察者。
注意:不要忘记解除注册,否则会导致资源泄露
#pragma mark //////////KVO方法//////////
//注册监听
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
//移除监听
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
//监听回调
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSString*, id> *)change context:(nullable void *)context;
使用KVO
Student.h文件
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
KVOViewController.m文件中
1.监听Student的属性
observer: 观察者对象
keyPath: 被观察的属性
options: 设定通知观察者时传递的属性值
context: 一些其他的需要传递给观察者的上下文信息
#import "KVOViewController.h"
#import "Student.h"
@interface KVOViewController ()
@end
@implementation KVOViewController{
Student *_student;
}
- (void)viewDidLoad {
[super viewDidLoad];
_student = [[Student alloc] init];
_student.name = @"LuisX";
_student.age = 24;
//为属性添加观察者
[_student addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(100, 100, 100, 100);
button.backgroundColor = [UIColor orangeColor];
[self.view addSubview:button];
[button addTarget:self action:@selector(changeStudentAgeValue:) forControlEvents:UIControlEventTouchUpInside];
}
@end
2.点击button修改student的属性
- (void)changeStudentAgeValue:(UIButton *)button{
_student.age++;
}
3.实现监听回调方法
keyPath: 被观察的属性
object: 被观察者的对象
change: 属性值,根据上面提到的Options设置,给出对应的属性值
context: 上面传递的context对象
//观察者通过实现下面的方法,完成对属性改变的响应
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"age"] && object == _student) {
NSLog(@"age:%ld", _student.age);
NSLog(@"old age:%@", [change objectForKey:@"old"]);
NSLog(@"new age:%@", [change objectForKey:@"new"]);
//输出: age:25
//输出: old age:24
//输出: new age:25
}
}
4.移除监听
- (void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
//移除观察者
[_student removeObserver:self forKeyPath:@"age"];
}