15:KVO (上) —— 使用篇

2020-04-27  本文已影响0人  小瞎_MarkDash

KVO 3个步骤 (自动调用)

对对象自动调用

@interface LGViewController ()
@property (nonatomic, strong) LGPerson  *person;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 1. 注册观察者
        [person addObserver:self
                 forKeyPath:@"name"
                    options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld
                    context:NULL];
    
    // 对象中被观察的属性发生变化
    person.name = @"Mark";    // 点语法
    [person setName:@"Dash"];    // setter
    [person setValue:nil forKey:@"name"];  // KVC
}

// 2. 监听回调
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    MDNSLog(@"keyPath: %@", keyPath);
    MDNSLog(@"object: %@", object);
    MDNSLog(@"change: %@", change);
}

// 3. 移除观察者
- (void)dealloc{
    [self.person removeObserver:self forKeyPath:@"name"];
}

@end

控制台打印↓

keyPath: name
object: <MDPerson: 0x600001561340>
change: {
    kind = 1;
    new = Mark;
    old = "<null>";
}
keyPath: name
object: <MDPerson: 0x600001561340>
change: {
    kind = 1;
    new = Dash;
    old = Mark;
}
keyPath: name
object: <MDPerson: 0x600001561340>
change: {
    kind = 1;
    new = "<null>";
    old = Dash;
}

对数组/集合自动调用

打印 change 时,里面的 kind 是什么?

context 有什么用?

父类和子类同时观察同一个 keyPath 引起问题

解决问题

context 通常用法

PS:以上问题只能用context解决,而下面的代码却有其他一些替代方案。意味着有些被广泛应用的特性其实是为了解决某个罕见问题,而我们却毫无察觉╮(╯▽╰)╭。

手动调用 KVO

对对象手动调用

对数组/集合手动调用

手动调用和自动调用的本质区别

C = A + B,如何在 A或B 发生变化时,能监听到C的值

复合路径的使用

意外情况

上一篇下一篇

猜你喜欢

热点阅读