什么是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:)时,优先查找 getKey、key、isKey、_key 方法。
  2. 成员变量次之:

    • 若未找到方法,且 +accessInstanceVariablesDirectly 返回 YES,则按顺序访问成员变量:
      _key → _isKey → key → isKey。

用途

  • 动态配置属性:通过字符串灵活读写属性(如解析 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:动态配置、反射、访问私有变量(谨慎使用)。
相关推荐
酒神dnspup6 小时前
多地区网站可用性监控怎么做?DNSPup 从基线到告警的完整实战
运维·ios·云计算·iphone·dns·网络监控
福兮说18 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic
茶底世界之下1 天前
时间线效果层,为什么不能只复用一个处理器?
ios·swift
ZZH_AI项目交付1 天前
实时字幕负责快,本地录音负责不丢:一个 iOS 录音功能为什么需要两条链路
ios·ai编程
Cc.Y1 天前
Swift深度链接的极简之道
ios·cocoa·swift
AI砖家1 天前
iPhone Duo 上架新规:旧 App 怎么兼容,还能不能继续更新?
ios·cocoa·iphone·ios上架·ios上架新规
黑科技iOS上架1 天前
小蟹iOS混淆:Objective-C项目实战
ios·审核·ios混淆·执行程序差异化
茶底世界之下1 天前
照片边缘太抢眼?用 Awaking 做一次 1:1 裁切
ios
Digitally1 天前
如何在iPhone上永久删除文件而无需恢复
ios·iphone
黑科技iOS上架1 天前
iOS二进制混淆实战:工程级指纹防护彻底解决4.3同质化拒审
ios·审核·ios混淆·执行程序差异化