iOS KVO

KVO

KVO的意思是Key Value Observering 键值观察
使得对象可以观察其他对象的属性 做出响应

非常适用的一个场景是用于更新UI
通常的更新UI的方式是 model通知控制器 需要更新某个属性值
这样的做法需要每个属性都写接口来更新
而且会导致代码非常冗余 因为控制器和model需要通过指针互相引用

而KVO可以让控制器知道模型的属性变化 从而直接更新UI

示例

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) UITextView *textView;
@property (nonatomic) int num;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.num = 0;
    self.textView = [[UITextView alloc] initWithFrame:CGRectMake(100, 100, 200, 50) textContainer:nil];
    [self.textView setText:[NSString stringWithFormat:@"num %d", self.num]];
    [self.view addSubview:self.textView];

    [self addObserver:self forKeyPath:@"num" options:NSKeyValueObservingOptionNew context:nil]; //注册KVO观察属性  属性名直接对应变量名
                   //observer是self是因为num是这个类的属性 如果num在另一个类里 就写那个类的对象
    self.num++; //修改属性值 触发KVO回调
}

- (void)dealloc
{
    [self removeObserver:self forKeyPath:@"num"]; //移除KVO
}

- (void)updateTextView
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.textView setText:[NSString stringWithFormat:@"num %d", self.num]]; //更新UI
    });
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    // KVO被触发 且属性是num
    if ([keyPath isEqualToString:@"num"]) {
        [self updateTextView];
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}


@end

KVO的实现原理

https://www.jianshu.com/p/91c41292b5b9

你可能感兴趣的:(iOS KVO)