zoukankan      html  css  js  c++  java
  • 使用KVC

    KVC是Key Value Coding的简称,意思是键值编码,号称Cocoa的大招。它是一种可以直接通过字符串key(对象在名称)来访问或修改对象属性的机制。


    使用

    1.利用KVC可以随意修改一个对象的属性或者成员变量(私有的也可以修改)。

    其中,key为被修改对象的名称或者其成员变量名称。

    #import <UIKit/UIKit.h>
    
    @interface MainTabBarController : UITabBarController
    
    @end
    @implementation MainTabBarController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // ZTTabBar是自定义的tabBar,这里要修改系统空间为自定义tabBar
        ZTTabBar *tabBar = [[ZTTabBar alloc] init];
        // self.tabBar = tabBar; 这里会报错,原因tabBar为readonly,所以这里考虑使用KVC。
        [self setValue:tabBar forKeyPath:@"tabBar"];
    }
    
    @end

    2.KVC: forKey、forKeyPath的区别,建议使用forKeyPath

    下面有两个示例类:

    1. Person类:name,age,dog及dogs四个属性;
    2. Dog类:name,number两个属性。
      (这个人很喜欢养狗)

    类:Person
    .h

    #import <Foundation/Foundation.h>
    
    @class Dog;
    
    @interface Person : NSObject
    
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, assign) int age;
    
    @property (nonatomic, strong) Dog *dog;
    @property (nonatomic, strong) NSArray *dogs;
    
    - (void)printHeight;
    @end

    .m

    #import "Person.h"
    
    @implementation Person
    {
        @private
        double _height; // 身高
    }
    
    @end

    类Dog
    .h

    #import <Foundation/Foundation.h>
    
    @interface Dog : NSObject
    
    @property (nonatomic, copy) NSString *name; //名字
    @property (nonatomic, assign) Int *number; //数量
    
    @end

    .m

    #import "Dog.h"
    
    @implementation Dog
    
    @end

    使用KVC修改属性:

    - (void)testKVC
    {
        Person *p = [[Person alloc] init];
        // 1.property
        p.name = @"rose";
        p.age = 20;
        p.dog = [[Dog alloc] init];
        p.dog.name = "旺财";
    
        // 2.forkey
        [p setValue:@"jack" forKey:@"name"];
        [p setValue:@30 forKey:@"age"];
        [p.dog setValue:@"旺福" forKey:@"name"];
    
        //Person对象的私有变量_height,对两个key:height\_height,任意一个key都可以修改其属性。
        //(对于height,KVC先从内存中寻找对应名为height的属性,如果找不到就会自动寻找_height,然后进行相应的修改)
        [p setValue:@1.80 forKey:@"height"];
        [p setValue:@1.85 forKey:@"_height"];
    
        // 3.forKeyPath
        // forKeyPath包含了forKey的功能,以后使用forKeyPath就可以了。
        // forKeyPath可以利用‘ . ’运算符一层一层往下查找对象的属性
        [p setValue:@"jack" forKeyPath:@"p.name"];
        [p setValue:@30 forKeyPath:@"p.age"];
    
        [p setValue:@"哈士奇" forKeyPath:@"dog.name"];
    
        NSLog(@"%d %@",  p.age,  p.name);
    }

    3. KVC取值

    - (void)useKVCGetValue
    {
        Person *p = [[Person alloc] init];
        p.dog = [[Dog alloc] init];
        [p setValue:@"妞妞" forKeyPath:@"dog.name"];
    
        NSLog(@"%@", [p valueForKeyPath:@"dog.name"]);
    }

    4.KVC Tips

    - (void)test
    {
          Person *p = [[Person alloc] init];
    
          Dog *dog1 = [[Dog alloc] init];
          dog1.name = @"中华田园犬"; // 看家还得看土狗
          dog1.number = 3;
    
          Dog *dog2 = [[Dog alloc] init];
          dog2.name = @"哈士奇"; // 二货,这玩意不能多养
          dog2.number = 1;
    
          Dog *dog3 = [[Dog alloc] init];
          dog3.name = @"柴犬";
          dog3.number = 4;
    
          Dog *dog4 = [[Dog alloc] init];
          dog3.name = @"萨摩耶";
          dog3.number = 3;
    
          Dog *dog5 = [[Dog alloc] init];
          dog5.name = @"黑背";
          dog5.number = 3;
    
          p.dogs = @[dog1, dog2, dog3, dog4, dog5];
          1. tip1:取指定数组
          // 取出dogs数组中每一个元素的name属性值,放到一个新的数组中返回
          NSArray *dogNames = [p valueForKeyPath:@"dogs.name"];
    
          2.tip2: @sum(求和),@avg(求平均数),更多tip请百度。
          // 计算所有狗的个数
          NSNumber *dogsNumber = [p valueForKeyPath:@"dogs.@sum.number"];
          NSLog(@"%@", sumNumber);
    }

    总结

    1. key的值必须正确,如果拼写错误,会出现异常;
    2. valueForKey valueForKeyPath 方法根据key的值读取对象的属性,setValue:forKey: forKeyPath: 是根据key的值来写对象的属性;
    3. 推荐使用 valueForKeyPath setValue:forKeyPth;
    4. 当key的值是没有定义的,valueForUndefinedKey:这个方法会被调用,如果重写了这个方法,就可以获取错误的key值。



    原文链接:http://www.jianshu.com/p/0e358f18950e

  • 相关阅读:
    Uboot命令使用
    git删除某次提交
    chrome随意改变主题
    C++11——处理日期和时间的chrono库
    C++11——多线程异步操作
    C++11——原子变量
    C++11——C++线程同步之条件变量
    C++11——C++线程同步之互斥锁
    C++11——call_once
    C++11——命名空间
  • 原文地址:https://www.cnblogs.com/isItOk/p/5791638.html
Copyright © 2011-2022 走看看