什么是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:动态配置、反射、访问私有变量(谨慎使用)。
相关推荐
未来侦察班7 小时前
一晃13年过去了,苹果的Airdrop依然很坚挺。
macos·ios·苹果vision pro
锐意无限13 小时前
Swift 扩展归纳--- UIView
开发语言·ios·swift
符哥200813 小时前
用Apollo + RxSwift + RxCocoa搭建一套网络请求框架
网络·ios·rxswift
文件夹__iOS17 小时前
AsyncStream 进阶实战:SwiftUI 全局消息流极简实现
ios·swiftui·swift
2501_9160088920 小时前
深入解析iOS机审4.3原理与混淆实战方法
android·java·开发语言·ios·小程序·uni-app·iphone
忆江南20 小时前
Flutter深度全解析
ios
山水域20 小时前
Swift 6 严格并发检查:@Sendable 与 Actor 隔离的深度解析
ios
楚轩努力变强21 小时前
iOS 自动化环境配置指南 (Appium + WebDriverAgent)
javascript·学习·macos·ios·appium·自动化
游戏开发爱好者82 天前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
黑码哥2 天前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder