iOS - KVC

2021-03-10  本文已影响0人  CDLOG

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"]);
上一篇下一篇

猜你喜欢

热点阅读