iOS面试总结

OC语言之KVO与KVC

2019-06-14  本文已影响0人  Jimmy_L_Wang

KVO

什么是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

- (void)setValue:(nullable id)value forKey:(NSString *)key;
- (nullable id)valueForKey:(NSString *)key;

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

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

valueForKey:的系统实现流程?

实现流程.png

Accessor Method是否存在的判断规则

Instance var

实现流程.png
上一篇 下一篇

猜你喜欢

热点阅读