iOS - KVC

作者: CDLOG | 来源:发表于2021-03-10 17:10 被阅读0次

    KVC-键值编码
    KVC:对象取值或者设置值。
    KVO:监听对象值的变化。

    获取对象值的优先级

    OC对象的属性是由3部分组成的,包括成员变量,setter方法,getter方法。
    KVC原理图


    image.png

    KVC取值优先级

    1,查找对象的相关方法(getName,name,isName)。
    2,看对象+(BOOL)accessInstanceVariablesDirectly的返回值,YES就查找成员变量,NO就报异常。
    3,成员变量优先级。
    例如获取name的值

    PersonModel *model = [[PersonModel alloc]init];
        NSLog(@"%@",[model valueForKey:@"name"]) ;
    

    对象方法高于成员变量,三个获取值的get方法,优先级如下

    -(NSString *)getName{
        return @"1111";
    }
    
    -(NSString *)name{
        return @"2222";
    }
    -(NSString *)isName{
        return @"3333";
    }
    
    

    成员变量查找优先级依次如下,只要存在声明就会优先,不管有没有值

    @interface PersonModel : NSObject{
        NSString *_name;
        NSString *_isName;//注意大写
        NSString *name;
        NSString *isName;//注意大写
    }
    

    KVC设值

    KVC设置值优先级和取值类似

    1,查找对象的相关方法(setKey,setIsName)。
    2,看对象+(BOOL)accessInstanceVariablesDirectly的返回值,YES就查找成员变量,NO就报异常。
    3,成员变量优先级,外界可以通过KVC修改成员变量。
    例子,通过KVC设置person的name

     PersonModel *person = [[PersonModel alloc]init];
        [person setValue:@"kvo" forKey:@"name"];
    

    相关方法

    -(void)setName:(NSString *)name{
        NSLog(@"setName%@",name);
    }
    -(void)setIsName:(NSString *)name{
        NSLog(@"setIsName%@",name);
    }
    

    知识点

    1,嵌套的拿数据方法valueForKeyPath,例如person里的dog的age属性,依次查找dog和age,查找方法和valueForKey是一样的。

    id age = [person valueForKeyPath:@"dog.age"];
    
    

    2,找不到成员变量报异常避免崩溃的方法

    -(id)valueForUndefinedKey:(NSString *)key{
        return nil;
    }
    -(void)setValue:(id)value forUndefinedKey:(NSString *)key{
        NSLog(@"没有找到%@",key);
    } 
    -(void)setNilValueForKey:(NSString *)key{
        NSLog(@"不能将%@设置为nil",key);
    }
    
    

    利用runtime获取对象的全部成员变量

    /// 获取对象全部的成员变量
    -(void)getAllProperty{
        unsigned int count = 0;
        //将对象的成员属性列表拷贝出来,count引用传递,可以拿到对象成员变量的个数
        Ivar *ivars = class_copyIvarList([self class], &count);
        //
        NSMutableArray *arr = [NSMutableArray array];
        
        for (int i = 0; i<count; i++) {
            Ivar ivar = ivars[i];
            const char *name = ivar_getName(ivar);
            NSString *propertyName = [NSString stringWithUTF8String:name];
            [arr addObject:propertyName];
        } 
        
        NSLog(@"\n-----%@的成员变量-----\n%@\n------------------------------",NSStringFromClass([self class]),arr);
        free(ivars);
        
    }
    

    KVC的运算符

    PersonModel *p1 = [[PersonModel alloc]init];
        p1.age = 13;
        PersonModel *p2 = [[PersonModel alloc]init];
        p2.age = 11;
        PersonModel *p3 = [[PersonModel alloc]init];
        p3.age = 15;
        
        NSMutableArray *arr = [NSMutableArray array];
        [arr addObjectsFromArray:@[p1,p2,p3]];
        //KVC的运算符,主要针对数组,包括@max,@min,@sum,@avg,@count
        NSLog(@"属性中的最大值是%@",[arr valueForKeyPath:@"@max.age"]);
    

    相关文章

      网友评论

          本文标题:iOS - KVC

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