Objective-C 「KVO键值观察」

《Objective-C 「KVO键值观察」》 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"];
}
    原文作者:LuisX
    原文地址: https://www.jianshu.com/p/785220b30c3d
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞