iOS——简单使用KVO

什么是KVO

KVO全称Key Value Observing,是苹果提供的一套事件通知机制。允许对象监听另一个对象特定属性的改变,并在改变时接收到事件。由于 KVO 的实现机制,只针对属性才会发生作用,一般继承自 NSObject 的对象都默认支持 KVO。

KVO的用法

使用KVO大概分为三个步骤

注册观察者

注册观察者的方法为addObserver:forKeyPath:options:context:,这个方法的四个参数作用为:
1.observer:观察者。
2. keyPath:被观察者,即为观察的属性,名字要和声明的一致
3. options:配置KVO机制,有下面四个参数。
1、NSKeyValueObservingOptionNew 把更改之前的值提供给处理方法
2、NSKeyValueObservingOptionOld 把更改之后的值提供给处理方法
3、NSKeyValueObservingOptionInitial 把初始化的值提供给处理方法,一旦注册,立马就会调用一次。通常它会带有新值,而不会带有旧值。
4、NSKeyValueObservingOptionPrior 分2次调用。在值改变之前和值改变之后。
4. context: 可以是任意类型的参数,可以传值

 [_aKvo addObserver:self forKeyPath:@"kvoString" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

实现回调方法

回调方法为 observeValueForKeyPath:ofObject:change:context:,当被观察的属性发生变化时,KVO机制会调用次方法来通知观察者。

// 设置按钮触发监听
- (void)pressChange {
    NSDictionary *aDictionary = [NSDictionary dictionaryWithObjectsAndKeys:_kvoTextField.text,@"kvoString", nil];
    [_aKvo setValuesForKeysWithDictionary:aDictionary];
    
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    
    if ([keyPath isEqualToString:@"kvoString"]) {
        NSLog(@"old nameWord: %@", [change objectForKey:@"old"]);
        NSLog(@"new nameWord: %@", [change objectForKey:@"new"]);
    }
    
}

在结束监听后,移除KVO

调用removeObserver:forKeyPath:方法将KVO移除。需要注意的是,调用removeObserver需要在观察者消失之前,否则会导致Crash.

- (void)dealloc {
    
    [_aKvo removeObserver:self forKeyPath:@"kvoString"];
    
}

以下是demo的完整代码
创建一个类继承NSObject,里面声明一个被监听的属性

//  KVO监听
//
//  Created by 差不多先生 on 2021/8/4.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Kvo : NSObject
@property (nonatomic, strong) NSString* kvoString;
@end

NS_ASSUME_NONNULL_END

ViewController

#import <UIKit/UIKit.h>
#import "message.h"
#import "Kvo.h"
@interface ViewController : UIViewController <
UITextFieldDelegate
>
@property (nonatomic, strong) Kvo* aKvo;
@property (nonatomic, strong) UITextField* kvoTextField;
#import "ViewController.h"
#import "Kvo.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor systemBlueColor];
    _aKvo = [[Kvo alloc] init];
    _aKvo.kvoString = @"XUPT";
    [_aKvo addObserver:self forKeyPath:@"kvoString" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
    _kvoTextField = [[UITextField alloc] init];
    _kvoTextField.backgroundColor = [UIColor whiteColor];
    _kvoTextField.frame = CGRectMake(100, 100, 200, 50);
    _kvoTextField.placeholder = _aKvo.kvoString;
    _kvoTextField.delegate = self;
    [self.view addSubview:_kvoTextField];
    UIButton* startButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    startButton.frame = CGRectMake(100, 170, 100, 50);
    [startButton setTitle:@"start" forState:UIControlStateNormal];
    [startButton setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
    [startButton addTarget:self action:@selector(pressChange) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:startButton];
}
// 设置按钮触发监听
- (void)pressChange {
    NSDictionary *aDictionary = [NSDictionary dictionaryWithObjectsAndKeys:_kvoTextField.text,@"kvoString", nil];
    [_aKvo setValuesForKeysWithDictionary:aDictionary];
    
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    
    if ([keyPath isEqualToString:@"kvoString"]) {
        NSLog(@"old nameWord: %@", [change objectForKey:@"old"]);
        NSLog(@"new nameWord: %@", [change objectForKey:@"new"]);
    }
    
}
- (void)dealloc {
    
    [_aKvo removeObserver:self forKeyPath:@"kvoString"];
    
}
@end

文章参考:iOS KVO 详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值