面试题答案
一键面试KVO实现机制
- 原理基础:KVO 基于观察者模式,当被观察对象的特定属性发生变化时,会自动通知观察者。这一机制依赖于运行时的动态特性。
- 自动通知机制:
- isa 混写:当对一个对象的属性进行 KVO 观察时,系统会动态创建该对象类的一个子类,并将被观察对象的
isa
指针指向这个新的子类。这个新子类重写了被观察属性的 setter 方法。 - 通知发送:当属性值改变调用 setter 方法时,新子类的 setter 方法除了设置属性值,还会发送通知给观察者。系统通过
NSKeyValueChange
结构体来封装属性变化的相关信息,如旧值、新值等。
- isa 混写:当对一个对象的属性进行 KVO 观察时,系统会动态创建该对象类的一个子类,并将被观察对象的
自定义KVO观察
- 关键步骤:
- 注册观察:使用
addObserver:forKeyPath:options:context:
方法,在需要观察的对象上注册观察者。addObserver
参数为观察者对象。forKeyPath
为被观察属性的键路径。options
用于指定观察选项,如是否获取旧值、新值等。context
是一个可选的指针,用于在回调时区分不同的观察情况。
- 实现回调方法:观察者需要实现
observeValueForKeyPath:ofObject:change:context:
方法,当被观察属性变化时,系统会调用此方法,在该方法中处理属性变化的逻辑。 - 移除观察:在不再需要观察时,调用
removeObserver:forKeyPath:
方法,从被观察对象上移除观察者,避免内存泄漏。
- 注册观察:使用
- 关键方法:
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"];