什么是KVO 、什么是 KVC ?

KVO(Key-Value Observing,键值观察)

是什么?

KVO 是 Objective-C/Swift 中的一种 观察者模式,允许对象监听另一个对象的属性变化。当被监听属性的值被修改时,观察者会自动收到通知。

核心机制

  1. 动态子类

    • 当对象首次被监听时,Runtime 会动态生成一个子类(如 NSKVONotifying_ClassName)。
    • 重写被监听属性的 setter 方法,插入 willChangeValueForKey:didChangeValueForKey: 方法。
  2. 消息转发

    • 修改对象的 isa 指针,指向动态子类,隐藏实现细节。
    • 当属性被修改时,通过 didChangeValueForKey: 触发观察者的回调。

用途

  • 数据与 UI 同步:例如,模型数据变化时自动更新界面。
  • 跨组件通信:解耦不同模块间的依赖关系。

示例

objc 复制代码
// 监听 person 的 age 属性
[person addObserver:self 
        forKeyPath:@"age" 
           options:NSKeyValueObservingOptionNew 
           context:nil];

// 回调方法
- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context {
    if ([keyPath isEqualToString:@"age"]) {
        NSLog(@"新年龄:%@", change[NSKeyValueChangeNewKey]);
    }
}

KVC(Key-Value Coding,键值编码)

是什么?

KVC 是一种通过 字符串键(Key)间接访问对象属性 的机制,无需直接调用 getter/setter 方法,甚至可以直接访问私有成员变量。

核心机制

  1. 方法优先

    • 赋值setValue:forKey:)时,优先查找 setKey:_setKey: 方法。
    • 取值valueForKey:)时,优先查找 getKeykeyisKey_key 方法。
  2. 成员变量次之

    • 若未找到方法,且 +accessInstanceVariablesDirectly 返回 YES,则按顺序访问成员变量:
      _key_isKeykeyisKey

用途

  • 动态配置属性:通过字符串灵活读写属性(如解析 JSON 数据)。
  • 访问私有变量:调试或特殊场景下访问私有成员。
  • 简化代码 :避免硬编码大量的 getter/setter 调用。

示例

objc 复制代码
// 通过 KVC 设置属性
[person setValue:@25 forKey:@"age"];

// 通过 KVC 读取属性
NSNumber *age = [person valueForKey:@"age"];

KVO 与 KVC 的区别

特性 KVO KVC
核心功能 监听属性变化 通过字符串键间接访问属性
底层机制 动态生成子类,重写 setter 方法查找 + 成员变量访问
主要用途 数据同步、跨组件通信 动态读写属性、访问私有变量
触发条件 必须通过 setter 或 KVC 修改属性 直接通过 setValue:forKey: 操作
复杂度 需手动管理观察者生命周期 无需额外管理

常见问题

1. 为什么 KVO 监听属性必须用字符串 KeyPath?

  • 动态性:字符串 KeyPath 允许运行时动态绑定属性,但容易拼写错误(编译器不检查)。

2. KVC 能修改私有变量吗?

  • 可以 :若 +accessInstanceVariablesDirectly 返回 YES,且私有变量命名符合 KVC 规范(如 _key)。

3. KVO 不移除观察者会崩溃吗?

  • :观察者释放后,若被观察对象仍发送通知,会导致野指针访问(EXC_BAD_ACCESS)。

总结

  • KVO 是 iOS 中实现 属性监听 的核心机制,依赖 Runtime 动态派发。

  • KVC 提供了一种 灵活访问属性 的方式,但需注意命名规范和安全性。

  • 适用场景

    • KVO:数据驱动 UI、跨层级通信。
    • KVC:动态配置、反射、访问私有变量(谨慎使用)。
相关推荐
lilili啊啊啊6 小时前
IOS奔溃日志分析-克魔ios开发助手实战-以支付宝奔溃日志为例
ios
lichao8904278 小时前
JBDev - Theos下一代越狱开发工具
ios
二流小码农11 小时前
鸿蒙开发:使用Ellipse绘制椭圆
android·ios·harmonyos
二流小码农12 小时前
鸿蒙开发:使用Circle绘制圆形
android·ios·harmonyos
Macle_Chen12 小时前
XCode中使用MonkeyDev开发iOS版的Comand-line Tool的daemon程序
macos·ios·xcode·逆向·comand-line
二流小码农13 小时前
鸿蒙开发:使用Rect绘制矩形
android·ios·harmonyos
丁乾坤的博客15 小时前
iOS审核被拒:Missing privacy manifest 第三方库添加隐私声明文件
ios·manifest·第三方库隐私文件
Unlimitedz17 小时前
iOS GCD
macos·ios·cocoa
布多17 小时前
AutoreleasePool:iOS 内存管理乐章中的隐秘旋律
ios·源码阅读
YungFan17 小时前
SwiftUI-国际化
ios·swiftui·swift