实现深层次监听的方法
- 使用KVO(Key-Value Observing)结合递归:
- 为外层对象添加KVO监听,当外层对象被监听的属性发生变化时,检查该属性是否为对象类型。
- 如果是对象类型,为该嵌套对象的相关属性再添加KVO监听,以此类推,实现递归监听。
- 示例代码如下:
// 假设OuterClass有一个InnerClass类型的属性innerObject
@interface OuterClass : NSObject
@property (nonatomic, strong) InnerClass *innerObject;
@end
@interface InnerClass : NSObject
@property (nonatomic, strong) NSString *name;
@end
@implementation OuterClass
- (void)addDeepObserving {
[self addObserver:self forKeyPath:@"innerObject" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"innerObject"]) {
InnerClass *newInnerObject = change[NSKeyValueChangeNewKey];
if (newInnerObject) {
[newInnerObject addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
}
} else if ([keyPath isEqualToString:@"innerObject.name"]) {
// 处理innerObject的name属性变化
NSString *newName = change[NSKeyValueChangeNewKey];
NSLog(@"Inner object name changed to: %@", newName);
}
}
- (void)dealloc {
[self removeObserver:self forKeyPath:@"innerObject"];
if (self.innerObject) {
[self.innerObject removeObserver:self forKeyPath:@"name"];
}
}
@end
- 使用通知(NSNotification):
- 在嵌套对象内部,当属性变化时,发送通知。
- 外层对象注册接收这些通知来实现监听。
- 例如,在InnerClass的属性setter方法中发送通知:
@implementation InnerClass
- (void)setName:(NSString *)name {
_name = name;
[[NSNotificationCenter defaultCenter] postNotificationName:@"InnerObjectNameChanged" object:self userInfo:@{@"newName": name}];
}
@end
@implementation OuterClass
- (void)addDeepObserving {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInnerObjectNameChange:) name:@"InnerObjectNameChanged" object:nil];
}
- (void)handleInnerObjectNameChange:(NSNotification *)notification {
NSString *newName = notification.userInfo[@"newName"];
NSLog(@"Inner object name changed to: %@", newName);
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"InnerObjectNameChanged" object:nil];
}
@end
性能问题
- 大量KVO监听开销:如果嵌套层次较深且对象数量较多,为每个对象的属性添加KVO监听会消耗大量系统资源,包括内存和CPU时间。每次属性变化时,KVO机制都要进行通知的分发和处理,这会增加系统的负担。
- 递归处理的性能消耗:在递归添加KVO监听过程中,需要不断检查对象类型并添加新的监听,这会带来额外的性能开销,尤其是在对象结构复杂时。
- 通知的频繁发送与处理:使用通知机制时,如果属性变化频繁,频繁发送和接收通知会导致性能下降。通知中心需要处理大量的通知分发,接收者也需要频繁响应通知。
优化方法
- 减少不必要的监听:仔细评估哪些嵌套对象的属性真正需要监听,避免对无关属性添加监听。例如,只对可能影响业务逻辑的关键属性进行监听。
- 批量处理变化:可以设置一个标志位或使用队列,将多次属性变化合并处理,而不是每次变化都立即响应。这样可以减少处理频率,提高性能。
- 使用更轻量级的机制:对于一些简单的场景,可以考虑使用代理模式代替KVO或通知。代理模式可以更精准地控制事件的传递,避免全局通知带来的性能开销。同时,代理模式相对KVO来说,实现更简单,资源消耗也更小。