美文网首页
KVO & KVC 学习

KVO & KVC 学习

作者: Tony17 | 来源:发表于2020-02-28 08:49 被阅读0次

前言

在 OC 的学习过程中,KVO 和 KVC 是我们经常提到的。我一直没有很清楚的搞明白 KVC 是个啥。今天开看一下。

KVO & KVC

  • KVO 其实就是键值监听,用于监听对象值的改变。方便做一些和值相关的一些处理。
  • KVC 其实是键值编码,很多时候用于不知道具体的对象类型,但是知道它的属性名,甚至对象类型和属性名都不知道。需要对这个可能存在的属性做操作(赋值或取值)

KVO

OC 中的 KVO 机制常用于实现类的监听,在被监听的值改变的时候可以自动调用监听方法,用于解耦。

如果一个类被添加了KVO监听,则会自动把该类对象改为NSKVONotifying_XXX类,NSKVONotifying_XXX类是通过runtime创建的XXX类的子类。

KVO本质

  • 利用runtime动态生成一个子类(NSKVONotifying_XXX),并且让instance对象的isa指向这个全新的子类

  • 当修改instance对象的属性的时候,会调用Foundation_NSSeetXXXValueAndNotify函数

  • 方法调用流程:

    1. willChangeValueForKey:
    2. 父类原来的setter方法
    3. didChanageValueForKey:
    4. 内部触发监听器(Oberser)的监听方法: oberserValueForKeyPath:ofObject:change:context:
  • 手动触发监听器:

    • 手动顺序调用willChangeValueForKey:didChanageValueForKey:方法。
  • NSKVONotifying_XXX 生成的方法:

    1. setXX 内部调用Foundation_NSSeetXXXValueAndNotify函数
    2. class 返回原来的类,隐藏NSKVONotifying_XXX
    3. dealloc
    4. _isKVOA

如果要触发KVO机制,必须调用到set方法,如果使用直接复制的方式,则无法触发KVO

KVC

KVCkey-value-coding 的简称,是OC的特性之一.

常用API:

  • -(void)setValue:(id)value forKeyPath:(NSString *)keyPath;
  • -(void)setValue:(id)value forKey:(NSString *)key;
  • -(id)valueForKey:(NSString *)key;
  • -(id)valueForKeyPath:(NSString *)keyPath;

key 和 keyPath 的区别是,keyPath是多层级的,a.b.c 的方式来访问属性,key为当前层级,不可以访问子级。

KVC 原理

调用-(void)setValue:(id)value forKey:(NSString *)key的时候, 方法调用流程:

  1. setKey:
  2. _setKey:
  3. accessInstanceVariablesDirectly 这方法如果返回YES,跳转到第4步,如果返回NO,跳转到第5步
  4. 依次查找 _key、_isKey、key、isKey 如果找到了则直接赋值,如果没有找到,跳转到第5步
  5. 调用setValue:forUndefinedKey:
    setValueForKey.png

调用-(id)valueForKey:(NSString *)key的时候, 方法调用流程:

  1. 依次调用 getkey、key、isKey、_key 方法如果存在则直接返回,如果不存在则跳转到第2步
  2. accessInstanceVariablesDirectly 这方法如果返回YES,跳转到第3步,如果返回NO,跳转到第4步
  3. 依次查找 _key、_isKey、key、isKey 如果找到了则直接赋值,如果没有找到,跳转到第4步
  4. 调用valueForUndefinedKey:
valueForKey.png

最后

以上就是本篇的内容,势必会有一些遗漏和错误,欢迎斧正~

相关文章

网友评论

      本文标题:KVO & KVC 学习

      本文链接:https://www.haomeiwen.com/subject/nahkhhtx.html