MST

星途 面试题库

面试题:Objective-C中KVO的基本使用及原理

请阐述在Objective-C中如何使用KVO(键值观察)来监听对象属性的变化。详细说明注册KVO的步骤、如何实现回调方法以及KVO的基本原理。
11.6万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

注册KVO的步骤

  1. 准备被观察对象:确保被观察对象的属性是遵循KVO机制的。通常,属性需要通过@property声明,并使用@synthesize自动合成存取方法(在现代的Objective-C中,@synthesize通常可省略)。例如:
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@end
  1. 注册观察者:在观察者对象中,调用被观察对象的addObserver:forKeyPath:options:context:方法进行注册。例如:
Person *person = [[Person alloc] init];
[self addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
  • addObserver:参数为观察者对象,通常是self,表示当前对象进行观察。
  • forKeyPath:指定要观察的属性的键路径,这里是name
  • options:指定观察选项,如NSKeyValueObservingOptionNew表示观察新值,NSKeyValueObservingOptionOld表示观察旧值,也可以两者组合。
  • context:是一个指针,用于传递上下文信息,通常设为nil

实现回调方法

观察者需要实现observeValueForKeyPath:ofObject:change:context:方法,当被观察对象的属性值发生变化时,系统会调用该方法。例如:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"name"]) {
        NSString *newName = change[NSKeyValueChangeNewKey];
        NSLog(@"The name has changed to %@", newName);
    }
}
  • keyPath:发生变化的属性的键路径。
  • object:被观察的对象。
  • change:包含属性变化信息的字典,如NSKeyValueChangeNewKey对应新值,NSKeyValueChangeOldKey对应旧值。
  • context:注册时传递的上下文指针。

KVO的基本原理

  1. 动态生成子类:当一个对象注册为另一个对象属性的观察者时,运行时系统会动态创建被观察对象类的一个子类。例如,对于Person类,会创建一个类似NSKVONotifying_Person的子类。

  2. 方法重写:这个动态子类重写了被观察属性的存取方法。例如,对于name属性,会重写setName:方法。当调用setName:方法时,除了设置新值外,还会通知所有注册的观察者属性发生了变化。

  3. 通知机制:系统通过observeValueForKeyPath:ofObject:change:context:方法将属性变化的信息传递给观察者。观察者根据这些信息进行相应的处理。

  4. 内存管理:当不再需要观察时,观察者需要调用被观察对象的removeObserver:forKeyPath:方法取消观察,以避免内存泄漏。例如:

[person removeObserver:self forKeyPath:@"name"];