美文网首页
KVO学习笔记

KVO学习笔记

作者: 会跑的鱼_09 | 来源:发表于2020-12-07 14:01 被阅读0次

    使用时小技巧

    一、自动开关automaticallyNotifiesObserversForKey:,如果返回NO则对应的字段监听就需要手动触发了,在set方法中把变量的修改用willChangeValueForKey:和didChangeValueForKey:包裹

    - (void)setNick:(NSString *)nick{
        [self willChangeValueForKey:@"nick"];
        _nick = nick;
        [self didChangeValueForKey:@"nick"];
    }
    

    二、如果想对监听key做一个转换,例如想监听keyA,实际内容需要监听B和C两个属性的变化,通过keyPathForValuesAffectingValueForKey:进行转换即可

    + (NSSet<NSString *> *)keyPathsForValuesAffectingValueForKey:(NSString *)key{
        NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
        if ([key isEqualToString:@"downloadProgress"]) {
            NSArray *affectingKeys = @[@"totalData", @"writtenData"];
            keyPaths = [keyPaths setByAddingObjectsFromArray:affectingKeys];
        }
        return keyPaths;
    }
    

    三、对于数组的观察需要利用kvc的技术来进行

    //有这样一个对象,有一个NSMutableArray的属性
    @interface LGPerson : NSObject
    @property (nonatomic, strong) NSMutableArray *dateArray;
    @end
    
    //监听其属性变化 
    [self.person addObserver:self forKeyPath:@"dateArray" options:(NSKeyValueObservingOptionNew) context:NULL];
    
    //只有通过kvc的方法修改属性才能触发kvo的监听回调
    [[self.person mutableArrayValueForKey:@"dateArray"] addObject:@"1"];
    

    KVO的原理

    1.动态生成子类NSKVONotifiy_A,修改当前对象的isa,这样才进行消息转发时才会进到子类的方法列表中来。
    2.动态给子类添加setter方法,class方法,dealloc方法,_isKVOA方法。setter方法是为了能拦截赋值过程通知给观察者,class方法是为了调用[object class]方法时不对外暴露子类的信息,dealloc方法是为了在对象释放时把isa指回来,_isKVOA方法是为了标记当前类的是用于kvo的。
    3.在动态生成的setter方法中把消息转发给父类,调用父类的setter方法,并通知观察者属性变化。
    具体过程推荐学习iOS-底层原理 23:KVO 底层原理

    相关文章

      网友评论

          本文标题:KVO学习笔记

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