KVC(iOS)

作者: iOS_成才录 | 来源:发表于2015-11-12 19:50 被阅读650次

    KVC : key value coding

    一、用途:

    set

    • 单个值 setValue: forkey: // 只能给对象的直接属性赋值
    [p setValue:@"cjp" forKey:@"name"];
    
    • 多层赋值 setValue:forKeyPath 可以给对象的间接属性赋值. 多层赋值
       // 建议: 以后在开发中都使用setValue:forKeyPath:
                [p setValue:@"xiaoqiang" forKeyPath:@"dog.name"];
    
    • 给私有成员变量赋值
       //  [p setValue:@"cjp" forKey:@"_name"];
              
           [p setValue:@"cjp" forKeyPath:@"_name"]; // 推荐
    
           SEL sel = @selector(say);
           [p performSelector:sel];
           [p say];
    
    • 4 字典转模型
      • 注意点:
      • 1.如果想使用KVC进行字典转模型, 那么字典中的key必须和模型中的属性一模一样(个数 + 名称)
        • 否则报经典错误:this class is not key value coding-compliant for the key score.'
      • 2.如果使用KVC进行字典转模型, 只能对当前调用KVC方法的对象进行转换, 不能对它的属性的对象进行转换,意思就是说:对象中的对象无法转换,需要另行进行手动转换,再次处理
    • 5 setValuesForKeysWithDictionary:方法内部的实现原理
    1.会拿到字典中的key, 然后根据这个key取出字典中的值, 然后再根据这个key赋值给对象
            //   [p setValue:@"xxx" forKey:@"name"];
        
            [p setValuesForKeysWithDictionary:dict];
            NSLog(@"p.dog = %@", p.dog);
    

    get

    • 获取单个值
     NSString *name =  [p valueForKey:@"name"];
    
    • 获取多层值
    NSString *dogName = [p valueForKeyPath:@"dog.name"];
    
    • 模型转字典

    NSDictionary *dict = [p dictionaryWithValuesForKeys:@[@"name", @"money"]];

    + 获取数组中对象的值 
        ```objc
               Person *p1 = [Person new];
               p1.name = @"zs";
               p1.money = 111;
                
               Person *p2 = [Person new];
               p2.name = @"ls";
               p2.money = 222;
                           
               NSArray *arr = @[p1, p2];
               // 如果数组中的元素都是同一种类型的数据, 可以使用KVC获取数组中所有对象的某个属性的值
               NSArray *res = [arr valueForKeyPath:@"name"];
               NSLog(@"res = %@", res); // 获取去数组中name属性的所有值:zs,ls
    
    • 运算符
      id res1 = [arr valueForKeyPath:@"@avg.money"];  // @avg.money:求出money的平均值
      NSLog(@"res = %@", res1);
    

    完整实例:

        #import "ViewController.h"
        #import "Person.h"
        #import "Dog.h"
        
        @interface ViewController ()
         
        @end
        
        @implementation ViewController
        
        - (void)viewDidLoad {
            [super viewDidLoad];
        
            Person *p = [Person new];
            p.name = @"cjp";  
            p.money = 998;
        //    p.dog = [Dog new];
        //    p.dog.name = @"wangcai";
        //    p.dog.price = 110;
            
        //    NSLog(@"%@ , %f", p.name, p.money);
        #pragma mark 获取单个值 
            NSString *name =  [p valueForKey:@"name"];
            NSLog(@"name = %@", name);
            double money = [[p valueForKey:@"money"] doubleValue];
            NSLog(@"money = %f", money);
            
             
        #pragma mark 获取多层值
        //    NSString *dogName = [p valueForKey:@"dog.name"];
        //    NSString *dogName = [p valueForKeyPath:@"dog.name"];
        //    NSLog(@"dogName = %@", dogName);
            
        #pragma mark 模型转字典
        //    NSDictionary *dict = [p dictionaryWithValuesForKeys:@[@"name", @"money"]];
        //    NSLog(@"%@", dict);
            
              
        #pragma mark 获取数组中对象的值
            
            Person *p1 = [Person new];
            p1.name = @"zs";
            p1.money = 111;
             
            Person *p2 = [Person new];
            p2.name = @"ls";
            p2.money = 222; 
            
            Person *p3 = [Person new];
            p3.name = @"ww";
            p3.money = 666;
             
            NSArray *arr = @[p1, p2, p3];
            
            // 如果数组中的元素都是同一种类型的数据, 可以使用KVC获取数组中所有对象的某个属性的值
            NSArray *res = [arr valueForKeyPath:@"name"]; 
            NSLog(@"res = %@", res);
            
        #pragma mark 运算符
            id res1 = [arr valueForKeyPath:@"@avg.money"];
            NSLog(@"res = %@", res1);
            
        }
        
        - (void)kvcSetter 
        { 
            Person *p = [[Person alloc] init];
            //    p.name = @"cjp"; // setter
            //    p.money = 998.0; 
        #pragma mark 单个值
            /*
             //      KVC == KEY VALUE CODING
             // Value : 值, 只能传对象
             // forKey: 需要给谁(哪个属性)赋值
             // setValue:forKey:方法, 只能给对象的直接属性赋值
             [p setValue:@"lmj" forKey:@"name"];
             // @(998.0) == [NSNumber numberWithDouble:(double)]
             [p setValue:@(668.0) forKey:@"money"];
             */
            
        #pragma mark 多层赋值  
            p.dog = [Dog new];
            /*
             //    p.dog.name == [[p dog] setName:]
             //    p.dog.name = @"wangwang";
             //    p.dog.price = 110.0;
             // setValue:forKeyPath: 可以给对象的间接属性赋值. 多层赋值
             // 建议: 以后在开发中都使用setValue:forKeyPath:
             //    [p setValue:@"xiaoqiang" forKeyPath:@"dog.name"];
             //    [p setValue:@(110) forKeyPath:@"dog.price"];
              */ 
        #pragma mark 给私有成员变量赋值 
            /*
             //    [p setValue:@"cjp" forKey:@"_name"];
             //    [p setValue:@(30) forKey:@"_age"];
             
             //    SEL sel = @selector(say);
             //    [p performSelector:sel];
             //    [p say];
             */
            
        #pragma mark 字典转模型  
            
            NSDictionary *dict = @{
                                   @"name":@"xxx",
                                   @"money": @(998.1),
                                   //                           @"score":@(100)
                                   @"dog":@{
                                           @"name":@"wangcai",
                                           @"price":@(110)
                                           }
                                   };
             
            //    p.name = dict[@"name"]; 
            //    p.money = [dict[@"money"] doubleValue];
            
              
            // 注意点:
            // 1.如果想使用KVC进行字典转模型, 那么字典中的key必须和模型中的属性一模一样(个数 + 名称)
            //  this class is not key value coding-compliant for the key score.'
            // 2.如果使用KVC进行字典转模型, 只能对当前调用KVC方法的对象进行转换, 不能对它的属性的对象进行转换
            
            // setValuesForKeysWithDictionary:方法内部的实现原理
            // 1.会拿到字典中的key, 然后根据这个key取出字典中的值, 然后再根据这个key赋值给对象
            //   [p setValue:@"xxx" forKey:@"name"]; 
            [p setValuesForKeysWithDictionary:dict];
            
            NSLog(@"p.dog = %@", p.dog);
            
            NSLog(@"name = %@, money = %f", p.name, p.money); // getter
            //    NSLog(@"name = %@, price = %f", p.dog.name, p.dog.price);
        }
        @end
    

    相关文章

      网友评论

        本文标题: KVC(iOS)

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