MST

星途 面试题库

面试题:Objective-C中KVO的实现机制及自定义观察的处理

深入分析Objective-C中KVO(Key - Value Observing)的实现机制,包括系统如何自动通知观察者。如果需要自定义KVO观察,应该如何进行处理,涉及哪些关键步骤和方法?
16.0万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

KVO实现机制

  1. 原理基础:KVO 基于观察者模式,当被观察对象的特定属性发生变化时,会自动通知观察者。这一机制依赖于运行时的动态特性。
  2. 自动通知机制
    • isa 混写:当对一个对象的属性进行 KVO 观察时,系统会动态创建该对象类的一个子类,并将被观察对象的 isa 指针指向这个新的子类。这个新子类重写了被观察属性的 setter 方法。
    • 通知发送:当属性值改变调用 setter 方法时,新子类的 setter 方法除了设置属性值,还会发送通知给观察者。系统通过 NSKeyValueChange 结构体来封装属性变化的相关信息,如旧值、新值等。

自定义KVO观察

  1. 关键步骤
    • 注册观察:使用 addObserver:forKeyPath:options:context: 方法,在需要观察的对象上注册观察者。
      • addObserver 参数为观察者对象。
      • forKeyPath 为被观察属性的键路径。
      • options 用于指定观察选项,如是否获取旧值、新值等。
      • context 是一个可选的指针,用于在回调时区分不同的观察情况。
    • 实现回调方法:观察者需要实现 observeValueForKeyPath:ofObject:change:context: 方法,当被观察属性变化时,系统会调用此方法,在该方法中处理属性变化的逻辑。
    • 移除观察:在不再需要观察时,调用 removeObserver:forKeyPath: 方法,从被观察对象上移除观察者,避免内存泄漏。
  2. 关键方法
    • addObserver:forKeyPath:options:context::用于注册观察。
    • observeValueForKeyPath:ofObject:change:context::观察回调方法,处理属性变化。
    • removeObserver:forKeyPath::移除观察。

例如:

// 注册观察
[someObject addObserver:self forKeyPath:@"someProperty" options:NSKeyValueObservingOptionNew context:nil];

// 实现回调
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"someProperty"]) {
        id newValue = change[NSKeyValueChangeNewKey];
        // 处理新值
    }
}

// 移除观察
[someObject removeObserver:self forKeyPath:@"someProperty"];