美文网首页
KVC的原理

KVC的原理

作者: 凌云01 | 来源:发表于2020-08-11 10:11 被阅读0次

    KVC的全称是Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性。
    主要有以下四种方法:

    //赋值方法
    - (void)setValue:(id)value forKey:(NSString *)key;
    - (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
    //取值方法
    - (id)valueForKey:(NSString *)key;
    - (id)valueForKeyPath:(NSString *)keyPath;
    

    下面我们通过相关代码来探索,新建一个Person类,一个Cat类

    @interface Cat : NSObject
    @property (nonatomic, assign) int weight;
    
    @end
    
    @implementation Cat
    
    @end
    
    
    @interface Person : NSObject
    
    @property (nonatomic, assign) int age;
    
    @property (nonatomic, strong) Cat *cat;
    
    @end
    
    @implementation Person
    
    - (void)setAge:(int)age {
       _age = age;
    }
    
    

    访问person的age

     Person *person = [[Person alloc] init];
     [person setValue:@10 forKey:@"age"];
     [person setValue:@10 forKeyPath:@"age"];
    
    NSLog(@"%d", person.age); 
    //打印 10
    person.age = 10;
    NSLog(@"%@---%@", [person valueForKey:@"age"], [person valueForKeyPath:@"age"]);
    打印 10---10
    

    通过打印结果发现这两种赋值方式,取出值都是10,说明setValue:forKey:和setValue:forKeyPath:没有区别。但是当我们访问Cat里面的属性时必须使用forKeyPath

        person.cat = [[Cat alloc] init];
        [person setValue:@20 forKeyPath:@"cat.weight"];//forKey则不能这样写
        NSLog(@"%@-----%d", [person valueForKeyPath:@"cat.weight"], person.cat.weight);
    //打印结果: 20-----20
    

    setValue:forKey:的原理

    setValue:forKey:流程
    • accessInstanceVariablesDirectly方法的默认返回值是YES

    当我们调用[person setValue:@10 forKey:@"age”];方法时,系统会依次做如下操作:
    查找Person类里面有没有setKey方法,如果没有则查找_setKey方法,如果查找到了就直接调用,如果都没有找到那么会调用accessInstanceVariablesDirectly方法,该方法是控制是否能访问成员变量,默认是返回YES,如果返回YES,则依次会查找Person类里面是否有_key,_isKey,key,isKey成员变量,如果有则赋值给它。如果都没有则抛出setValue:forUndefinedKey:异常。如果accessInstanceVariablesDirectly方法返回NO,也抛出setValue:forUndefinedKey:异常。

    valueForKey:的原理

    valueForKey:流程图

    当我们调用[person valueForKey:@"age"]方法时,系统会依次做如下操作:
    按顺序依次查找Person类里面有没有getKey,key,isKey,_key,如果有则直接调用方法,如果都没有找到,那么也会调用accessInstanceVariablesDirectly方法,该方法是控制是否能访问成员变量,默认是返回YES,如果返回YES,则依次会查找Person类里面是否有_key,_isKey,key,isKey成员变量,如果有则直接去成员变量的值,如果都没有则抛出setValue:forUndefinedKey:异常。如果accessInstanceVariablesDirectly方法返回NO,也抛出setValue:forUndefinedKey:异常。

    相关文章

      网友评论

          本文标题:KVC的原理

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