美文网首页iOS面试总结
OC语言之KVO与KVC

OC语言之KVO与KVC

作者: Jimmy_L_Wang | 来源:发表于2019-06-14 18:06 被阅读0次

KVO

什么是KVO?

  • KVO 是 Key-value observing(键值观察)的缩写。
  • KVO是Objective-C对观察者设计模式的又一实现。
  • Apple使用了isa混写(isa-swizzling)来实现KVO

KVO的实现机制是怎样的?

KVO实现机制.png

系统在运行时为我们动态创建了一个子类NSKVONotifying_A,改写isa的指向为这个子类,同时重写setter方法,来实现KVO的机制的

系统会在创建的NSKVONotifying_A的重写setter中调用下面两个方法:

//NSKVONotifying_A的setter实现
- (void)setValue:(id)obj
{
    [self willChangeValueForKey:@"keyPath"];
    //调用父类实现,也即原类的实现
    [super setValue:obj];
  //此方法会触发observeValueForKeyPath:回调
    [self didChangeValueForKey:@"keyPath"];
}

通过KVC设置value能否生效?

能,为什么可以生效。KVC的setValue:forKey:可以调用到被监听对象的setter方法。

通过成员变量直接赋值value能否生效?

不能。因为不能调用到被监听对象的setter方法。

如何实现手动的KVO监听

- (void)increase
{
    //直接为成员变量赋值
    [self willChangeValueForKey:@"value"];
    _value += 1;
    [self didChangeValueForKey:@"value"];//会触发observeValueForKeyPath:回调
}

Ps:监听者回调

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    
    if ([object isKindOfClass:[MObject class]] &&
         [keyPath isEqualToString:@"value"]) {
        
        // 获取value的新值
        NSNumber *valueNum = [change valueForKey:NSKeyValueChangeNewKey];
        NSLog(@"value is %@", valueNum);
    }
}

KVC

  • KVC是Key-value coding(键值编码)的缩写。
- (void)setValue:(nullable id)value forKey:(NSString *)key;
- (nullable id)valueForKey:(NSString *)key;

KVC是否有违背面向对象编程思想?

是的,上面的key是没有任何限制的,在我们知道一个类或实例它内部的某一个私有成员变量名称的情况下,我们在外界是可以通过已知的key来对他的私有成员变量进行设置或访问的操作,从这个层面上来讲是破坏了面向对象编程思想的。

valueForKey:的系统实现流程?

实现流程.png

Accessor Method是否存在的判断规则

  • <getKey>
  • <key>
  • <isKey>

Instance var

  • _key

  • _isKey

  • key

  • isKey

    setValue: forKey:调用流程

实现流程.png

相关文章

网友评论

    本文标题:OC语言之KVO与KVC

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