• OC-KVO和KVC


    KVC

    key value coding

    作用

    @interface A ; NSObject
    {
    	int age;//按这个顺序依次赋值 如果有上面的就不会给下面的赋值 是按命名规则 跟声明顺序无关 就是如果没有age 就给_age赋值 如果这些都没有则调用setValue:forUndefinedKey:
    	int _age;
    	int _isage;
    	int isage;
    }
    -(void)setAge:(int)a
    
    //取值则按这个顺序执行方法
    -(int)getName;
    -(int)name;
    -(int)isName;
    -(int)_Name;
    //如果没有这几个方法则先判断accessInstanceVariablesDirectly方法返回的是不是true 如果是就会直接去age,_age,_isage,isage获取值
    @end
    @implement A
    -(void)setAge:(int)a
    {
    	NSLog(@"@s",__func__);
    	_age = a;
    }
    @end
    int main()
    {
    	A *a = [[A alloc]init];
    	//设置值
    	[a setValue:@12 forKey:@"age"];//会调用setName或者_setName的方法进行赋值
    	//取值
    	NSLog(@"%d",[a valueForKey:@"age"])
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    KVO

    key value observe
    就是当被监视者的值发生改变的时候就会通知监视者
    addobserver设置监视者是谁 并且设置提供什么样的值 使用该方法后
    当被监视的值发生改变的时候就会将oberveValueForKeyPath的消息发给监视者

    KVO实现原理

    Stack* stack = [[Stack alloc]init];
    [stack addObserver:self forKeyPath:@"fido" options:NSKeyValueChangeOldKey | NSKeyValueObservingOptionNew context:NULL];
    
    • 1
    • 2

    当执行这个之后会动态生成一个NSKVONotifying_Stack类 然后让stack的isa指针指向NSKVONotifying_Stack类 系统会生成相应的setFido方法 然后set方法内部就会调用willChangeValueForKeydidChangeValueForKey

    addObserver:

    //在执行这消息之前是 Stack*类型
    [stack addObserver:self forKeyPath:@"fido" options:NSKeyValueChangeOldKey | NSKeyValueObservingOptionNew context:NULL];
    //执行之后变成NSKVONotifying_Stack类型 是NSKVONotifying 的子类 生成后 就算removeObserver之后 NSKVONotifying_Stack这个类还会存在 但是stack会变回Stack*
    
    //NSKeyValueObservingOldKey提供属性改变前的值
    //NSKeyValueObservingNewKey提供属性改变后的值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    NSKVONotifying_Stack会写一个setFido方法 这个是核心 在这个方法里 就会调用willChangeValueForKeydidChangeValueForKey

    observeValueForKeyPath:

    如果改变fido的值则会触发observeValueForKeyPath

    removeObserver: forKeyPath:

    需要在dealloc的时候移除观察者
    change的参数自己查 没太懂 这个函数应该不要自己主动调用 不知道这个参数是干嘛的

    手动关闭KVO automaticallyNotifiesObserversForKey

    +(BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
    {
    	return NO;
    }
    
    • 1
    • 2
    • 3
    • 4

    这样KVO就不会运行了

    手动触发KVO

        [self willChangeValueForKey:@"fido"];
        fido++;
        [self didChangeValueForKey:@"fido"];
    
    • 1
    • 2
    • 3

    KVC能触发KVO

  • 相关阅读:
    使用 Pyro 和 PyTorch 的贝叶斯神经网络
    ts面试题总结
    win10完美还原桌面图标快捷方式小箭头的方法
    第一章 行列式
    工业树莓派的应用:助力构建智慧能源管理系统
    gulimall基础篇回顾Day-08
    第七篇 python IO操作
    KMP算法
    ragflow 大模型RAG知识库使用案例
    第一天| 第一章 数组part01 数组理论基础、704. 二分查找、27. 移除元素
  • 原文地址:https://blog.csdn.net/qq_43535469/article/details/126426689