Object-C 中的 KVC

在开发中,我们有时候需要求改系统控件里面某个属性,但该属性未必是开放的。那么,我们会想各种办法来完成。比如

UITextField中placeholder的字体颜色。实现方法也很多,比如在用label啊,重写啊这些。我以前也经常这样做。

但是KVC就可以很简单的解决这个问题。

[self.textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];

在UITextField中placeholder字体颜色是私有属性,无法直接获取并修改,那么我们就可以使用KVC来实现。

 

[self.textField valueForKeyPath:@"_placeholderLabel.textColor"];

获取它的值!

总结:KVC可以获取和设置属性(包括该object的私有属性)!!!

赋值的实现过程,

1.查找是否有相关的方法set:, _set:, setIs:

2.当没有相关方法的时候判断是否可以直接方法成员变量。- (BOOL)accessInstanceVariablesDirectly;

3.如果是NO,则抛出异常。

4.如果为YES,继续找相关变量_  _is    is

5.如果方法和成员都不存在,则抛出异常。

取值的实现过程与赋值相似,就不做说明。

那么通过这里,我们也就知道,当你在赋值与取值的时候,使用的是不存在的key,就会抛出异常,当你没有实现异常方法的时候,就会出现闪退的情况!!!所以,我们最好添加上处理方法。

#pragma mark 赋值

//对非对象类型,值不能为空

- (void)setNilValueForKey:(NSString *)key{

    NSLog(@"%@ 值不能为空", key);

}

 

// 当key不存在的时候调用次方法

- (void)setValue:(id)value forUndefinedKey:(NSString *)key{

    NSLog(@"%@ key不存在", key);

}

 

#pragma mark 取值

- (id)valueForUndefinedKey:(NSString *)key{

    NSLog(@"key=%@ 不存在", key);

    return nil;

}

这里顺带一句。不是有一个万能储存容器么?其实就是这个异常帮忙处理的。

新建一个可变字典。

当抛出异常是,把key和value对应键值储存在字典。也就成了所说的万能储存容器!!!!

下面谈谈KVC的其他用法。

1.关于字典的一次性赋取值

    ZPPerson *p = [ZPPerson new];

    ///一次性赋值

    NSDictionary *dic = @{@"name": @"Tom", @"age":@"18", @"nick":@"壮壮", @"accontId":@"123871623871263", @"sex":@"男"};

    [p setValuesForKeysWithDictionary:dic];

    NSLog(@"name = %@  age = %d  nick = %@  accountId = %@  sex = %@", p.name, p.age, p.nick, p.accontId, p.sex);

    

    ///一次性取值

    NSArray *ary = @[@"name", @"age", @"nick", @"accontId", @"sex"];

    NSDictionary *dict = [p dictionaryWithValuesForKeys:ary];

    NSLog(@"dict:%@", dict);

在开发中其实挺好用的,根据接口文档,定义model中的成员,然后在接口返回数据的时候直接一句话搞定。不在需要去model中setData:NSDictionary(以前我就是这样,现在感觉自己像个白痴!!!)了,挺方便的。

2.消息传递

    NSArray *ary = @[@"阿卡多好看", @"asasjdkhaskjdh", @"爱上的开奖号阿圣诞快乐啊"];

    NSArray *aryLength = [ary valueForKey:@"length"];

只需要一句话,就能获取到上面数组中所有内容的长度。(注意数据类型,如果数组中是对象,他就没有length)。

3.聚合操作 @avg(取平均值)   @count(个数)   @max(最大值)   @min(最小值)   @sum(求和)

    NSMutableArray *ary = [[NSMutableArray alloc] init];

    for (int i = 0; i < 6; i++) {

        ZPPerson *p = [ZPPerson new];

        NSDictionary *dic = @{@"name": @"Tom", @"age":@(18+i), @"nick":@"壮壮", @"accontId":@(156*i+123123435), @"sex":@"男"};

        [p setValuesForKeysWithDictionary:dic];

        [ary addObject:p];

    }

    ///每个人的年龄

    NSLog(@"%@", [ary valueForKey:@"age"]);

    ///去所有人的平均值

//    NSNumber *num = [ary valueForKeyPath:@"@avg.age"];

    NSLog(@"%@", [ary valueForKeyPath:@"@avg.age"]);

3.数组操作 distinctUnionOfObjects (去重)  unionOfObjects(不去重)

/**

数组操作符  distinctUnionOfObjects  unionOfObjects

*/

- (void)demo4{

    NSMutableArray *ary = [[NSMutableArray alloc] init];

    for (int i = 0; i < 6; i++) {

        ZPPerson *p = [ZPPerson new];

        NSDictionary *dic = @{@"name": @"Tom", @"age":@(18+i), @"nick":@"壮壮", @"accontId":@(170 + 0.02*arc4random_uniform(6)), @"sex":@"男"};

        [p setValuesForKeysWithDictionary:dic];

        [ary addObject:p];

    }

    NSLog(@"%@", [ary valueForKey:@"accontId"]);

    //去重

    NSLog(@"%@", [ary valueForKeyPath:@"@distinctUnionOfObjects.accontId"]);

}

以后的开发中,去重就很简单了!

4.嵌套(array)操作  distinctUnionOfArrays   unionOfArrays  

- (void)demo5{

    NSMutableArray *ary = [[NSMutableArray alloc] init];

    for (int i = 0; i < 6; i++) {

        ZPPerson *p = [ZPPerson new];

        NSDictionary *dic = @{@"name": @"Tom", @"age":@(18+i), @"nick":@"壮壮", @"accontId":@(170 + 0.02*arc4random_uniform(6)), @"sex":@"男"};

        [p setValuesForKeysWithDictionary:dic];

        [ary addObject:p];

    }

    NSMutableArray *ary1 = [[NSMutableArray alloc] init];

    for (int i = 0; i < 6; i++) {

        ZPPerson *p = [ZPPerson new];

        NSDictionary *dic = @{@"name": @"Tom", @"age":@(18+i), @"nick":@"壮壮", @"accontId":@(170 + 0.02*arc4random_uniform(6)), @"sex":@"男"};

        [p setValuesForKeysWithDictionary:dic];

        [ary1 addObject:p];

    }

    //嵌套数组

    NSArray *list = @[ary,ary1];

    

    //去重

    NSLog(@"%@", [list valueForKeyPath:@"@distinctUnionOfArrays.accontId"]);

 

    //不去重

    NSLog(@"%@", [list valueForKeyPath:@"@unionOfArrays.accontId"]);

}

5.另外还有一个集合!!!!

    NSMutableSet *ary = [[NSMutableSet alloc] init];

    for (int i = 0; i < 6; i++) {

        ZPPerson *p = [ZPPerson new];

        NSDictionary *dic = @{@"name": @"Tom", @"age":@(18+i), @"nick":@"壮壮", @"accontId":@(170 + 0.02*arc4random_uniform(6)), @"sex":@"男"};

        [p setValuesForKeysWithDictionary:dic];

        [ary addObject:p];

    }

//    NSLog(@"%@", [ary valueForKey:@"accontId"]);

    

    NSMutableSet *ary1 = [[NSMutableSet alloc] init];

    for (int i = 0; i < 6; i++) {

        ZPPerson *p = [ZPPerson new];

        NSDictionary *dic = @{@"name": @"Tom", @"age":@(18+i), @"nick":@"壮壮", @"accontId":@(170 + 0.02*arc4random_uniform(6)), @"sex":@"男"};

        [p setValuesForKeysWithDictionary:dic];

        [ary1 addObject:p];

    }

//    NSLog(@"%@", [ary1 valueForKey:@"accontId"]);

    

    NSSet *set = [NSSet setWithObjects:ary, ary1, nil];

    NSLog(@"%@", [set valueForKey:@"accontId"]);

    NSLog(@"%@", [set valueForKeyPath:@"@distinctUnionOfSets.accontId"]);

你可能感兴趣的:(学习)