家庭网络如何做网站服务器,常用企业网站模板对比,泉州高端网站建设,石家庄网页设计制作在 iOS 中#xff0c;KVO#xff08;Key-Value Observing#xff09;是一个强大的观察机制#xff0c;它的底层实现相对复杂。KVO 利用 Objective-C 的动态特性#xff0c;为对象的属性提供观察能力。
KVO 的底层实现
1. 动态子类化
当一个对象的属性被添加观察者时KVOKey-Value Observing是一个强大的观察机制它的底层实现相对复杂。KVO 利用 Objective-C 的动态特性为对象的属性提供观察能力。
KVO 的底层实现
1. 动态子类化
当一个对象的属性被添加观察者时KVO 会在运行时动态地创建该对象的子类并重写该属性的 setter 方法。
动态创建子类KVO 会创建一个新的类这个新类是被观察对象的子类通常这个类的名字是 _NSKVOClassName_ClassName 形式。重写 setter 方法在这个动态创建的子类中KVO 会重写被观察属性的 setter 方法。
2. 重写 setter 方法
重写后的 setter 方法在属性值发生变化时会进行以下操作
触发 willChangeValue(forKey:)通知即将发生变化。调用原始 setter 方法通过消息转发机制调用原始的 setter 方法以实际更新属性值。触发 didChangeValue(forKey:)通知变化已经发生触发观察者回调。
3. 动态方法解析
在 KVO 动态创建的子类中使用 method_setImplementation 方法来重写属性的 setter 方法。
void setAge(id self, SEL _cmd, int newAge) {[self willChangeValueForKey:age];struct objc_super superStruct {.receiver self,.super_class class_getSuperclass(object_getClass(self))};((void (*)(struct objc_super *, SEL, int))objc_msgSendSuper)(superStruct, _cmd, newAge);[self didChangeValueForKey:age];
}KVO 的实现细节
以下是一个简单的示例展示了 KVO 的一些底层实现细节
interface Person : NSObject
property (nonatomic, assign) int age;
endimplementation Person
endPerson *person [[Person alloc] init];
NSLog(Original class: %, object_getClass(person)); // 输出原始类[person addObserver:self forKeyPath:age options:NSKeyValueObservingOptionNew context:nil];
NSLog(Class after adding observer: %, object_getClass(person)); // 输出动态子类[person setAge:30];
[person removeObserver:self forKeyPath:age];KVO 的工作流程 添加观察者 调用 addObserver:forKeyPath:options:context: 方法时KVO 会动态创建子类并重写 setter 方法。原始对象的类指针isa 指针被修改为新创建的子类。 触发观察 当属性值发生变化时调用重写后的 setter 方法。先触发 willChangeValueForKey:然后调用原始 setter 方法更新属性值最后触发 didChangeValueForKey:。触发 didChangeValueForKey: 时会通知所有观察者属性值已经改变。 移除观察者 调用 removeObserver:forKeyPath: 方法时KVO 会将类指针恢复为原始类并移除重写的 setter 方法。
注意事项
自动 KVOKVO 默认仅支持通过 setter 方法修改属性值的情况。直接修改实例变量不会触发 KVO。手动触发 KVO如果需要手动触发 KVO可以调用 willChangeValue(forKey:) 和 didChangeValue(forKey:) 方法。
[self willChangeValueForKey:age];
_age newValue;
[self didChangeValueForKey:age];总结
KVO 是 iOS 中基于动态特性实现的观察机制通过动态子类化和方法重写实现。当属性值变化时KVO 会通知所有注册的观察者。这一机制使得对象间的通信更加灵活和高效但也需要注意在使用过程中正确添加和移除观察者以避免内存泄漏或崩溃。