KVC与KVO

一、KVC

1、概念:KVC是键值编码,即NSKeyValueCoding。我们可以通过以字符串为Key对对象属性进行操作。

/**  通过传入字符串key获取或者设置类属性  **/
- (nullable id)valueForKey:(NSString *)key;
- (void)setValue:(nullable id)value forKey:(NSString *)key;

/**  keyPath:用点号连接的多层级的属性,例如 JZPerson.son  **/
- (nullable id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;

2、原理:

valueForKey查找方式:

1.访问器匹配:先寻找与key,isKey, getKey (实测还有_key)同名的方法,返回值为对象类型。

2.实例变量匹配:寻找与key, _key,isKey,_isKey同名的实例变量

setValueForKey查找方式:

1.存取器匹配:先寻找与setKey同名的方法,且参数要为一个对象类型

2.实例变量匹配:寻找与key,_isKey,_key,isKey同名的实例变量,直接赋值。

 

二、KVO

1、概念:KVO是键值观察,即NSKeyValueObserving。当一个对象被观察的属性发生变化时,观察者做出的处理。在 Objective-C 中有手动或自动两种键值观察的方式。

2、手动方式:

手动键值观察方式比较简单,就是在值发生变化时自动调用方法。

/**  name为类属性,手动调用willChangeValueForKey和didChangeValueForKey方法  **/
- (void)setName:(NSString *)name {
    [self willChangeValueForKey:@"name"];
    _name = name;
    [self didChangeValueForKey:@"name"];
}

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
    if ([key isEqualToString:@"name"]) {
        return NO;  // 返回NO实现手动键值观察
    }
    return [super automaticallyNotifiesObserversForKey:key];
}

3、自动方式:

通过addObserver方法实现对属性变化进行观察。

/**  通过控制器self对person的name属性变化进行观察  **/
self.person = [[JZPerson alloc] init];
[person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

/**  变化时调用方法  **/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    
}

// 移除观察
- (void)dealloc {
    [self.person removeObserver:self forKeyPath:@"name"];
}

实现原理:

当某个类的对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的 setter 方法。

派生类在被重写的 setter 方法实现真正的通知机制,就如前面手动实现键值观察那样。这么做是基于设置属性会调用 setter 方法,而通过重写就获得了 KVO 需要的通知机制。当然前提是要通过遵循 KVO 的属性设置方式来变更属性值,如果仅是直接修改属性对应的成员变量,是无法实现 KVO 的。

同时派生类还重写了 class 方法以“欺骗”外部调用者它就是起初的那个类。然后系统将这个对象的 isa 指针指向这个新诞生的派生类,因此这个对象就成为该派生类的对象了,因而在该对象上对 setter 的调用就会调用重写的 setter,从而激活键值通知机制。此外,派生类还重写了 dealloc 方法来释放资源。手动实现的方式并不会生成NSKVONotifying_xx派生类,只有自动方式才会生成派生类。

 

参考文献:

1、用代码探讨 KVC/KVO 的实现原理

2、详解键值观察(KVO)及其实现机理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值