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


使用

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

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

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

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

下面有两个示例类:

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

类:Person
.h

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

.m

  1. #import "Person.h"
  2. @implementation Person
  3. {
  4. @private
  5. double _height; // 身高
  6. }
  7. @end

类Dog
.h

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

.m

  1. #import "Dog.h"
  2. @implementation Dog
  3. @end

使用KVC修改属性:

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

3. KVC取值

  1. - voiduseKVCGetValue
  2. {
  3. Person *p = [[Person alloc] init];
  4. p.dog = [[Dog alloc] init];
  5. [p setValue:@"妞妞" forKeyPath:@"dog.name"];
  6. NSLog(@"%@", [p valueForKeyPath:@"dog.name"]);
  7. }

4.KVC Tips

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

总结

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

使用KVC的更多相关文章

  1. Objective-C之KVC、KVO

    1,KVC(键值编码)  Key Value Coding 1.1在C#中,可以通过字符串反射来获取对象,从而对对象的属性进行读写,Object-C中有同样的实现,通过字符串(属性名词)对对象的属性进 ...

  2. KVC 和 KVO

    KVC 键值编码    全称是Key-value coding,翻译成键值编码.它提供了一种使用字符串而不是访问器方法去访问一个对象实例变量的机制.        1.通过key(成员变量的名称)设置 ...

  3. 11. KVC And KVO

    1. KVC And KVO  的认识 KVC/KVO是观察者模式的一种实现  KVC全称是Key-value coding,翻译成键值编码.顾名思义,在某种程度上跟map的关系匪浅.它提供了一种使用 ...

  4. iOS开发系列--Objective-C之KVC、KVO

    概述 由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby.Python的动态特性,例如动态类型.动态加载.动态绑定等.今天我们着重介绍ObjC中的键值编码(KVC).键值监听( ...

  5. IOS学习之初识KVC

    什么是kvc? kvc (key-value coding )键值编码,是ios 提供的一种通过key间接的来访问对象属性的一直方式. 哪些类支持kvc操作? kvc的操作方法由NSKeyValueC ...

  6. KVC & KVO

    KVC和KVO看上去又是两个挺牛的单词简写,KVC是Key-Value Coding的简写,是键值编码的意思.KVO是Key-Value  Observing的简写,是键值观察的意思.那么我们能拿KV ...

  7. iOS - 详细理解KVC与KVO

    详细理解KVC与KVO 在面试的时候,KVC与KVO有些时候还是会问到的,并且他们都是Objective C的关键概念,在这里我们先做一个简单地介绍: (一)KVC: KVC即指:NSKeyValue ...

  8. KVC&&&KVO

    KVC 什么是KVC --->What KVC指的就是NSKeyValueCoding非正式协议. KVC是一种间接地访问对象的属性的机制. 这种间接表现在通过字符串来标识属性,而不是通过调用存 ...

  9. OC KVC

    OC KVC KVC 全称 key valued coding 键值编码 在说KVC之前应该简单的了解一下反射机制 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法. 对于任意 ...

  10. IOS开发之Bug--使用KVC的易错情况

    1.其实某些角度而言KVC是一个破坏封装又暴力的做法,而我已经两次因为KVC而导致应用程序出现闪退的情况. 场景:1.使用KVC修改某一个UIView的属性,比如width.    2.在viewWi ...

随机推荐

  1. Java设计模式08:框架基础知识

    1. 框架是什么 ? 框架是能完成一定功能的半成品软件.(不能直接使用,还需要再加工,所以叫半成品.比如:方便面) 2. 框架能干什么 ? (1)能完成一定的功能,加快程序开发进度. (2)给我们一个 ...

  2. 有效范围为request的bean

    Car.java类 package tom.jiafei; public class Car { String carnumber; String name; String date; public ...

  3. git 撤销修改以及删除文件

    撤销修改 1.如果当你修改了代码,然后又发现修改错误以后,想撤销前面的操作的时候该怎么办呢? 既然错误发现得很及时,就可以很容易地纠正它.你可以删掉最后一行,手动把文件恢复到上一个版本的状态.如果用 ...

  4. linux系统安装(虚拟机以及linux的下载与安装)

    最近开始研究linux系统,以前接触linux系统只是一些简单的命令,例如: pwd:查看当前目录   ls:遍历目录    cd :在目录之间切换等. linux系统是基于unix系统开发的,是一个 ...

  5. 【原】NGUI中的UIAnchor脚本功能

    UIAnchor的功能是把对象锚定在屏幕的边缘(左上,左中,左下,上,中,下,右上,右中,右下),或缩放物体使其匹配屏幕的尺寸. 在1.90版本后,拉长(缩放)的功能被放到UIStretch中,UIA ...

  6. DEDECMS 获取当前栏目及所有子栏目的文章数量

    因DEDEV5起,加强了对SQL注入和安全的检查,导致无法查询一些正常的子查询的SQL. 以下代码用来解决查询当前栏目及当前栏目下所有子栏目的文章总数,添加到/include/common.func. ...

  7. HDFS之SequenceFile和MapFile

    http://blog.csdn.net/javaman_chen/article/details/7241087 Hadoop的HDFS和MapReduce子框架主要是针对大数据文件来设计的,在小文 ...

  8. 支持状态对象复用的RPC框架——SnakeRPC

    SnakeRPC是我2年前(春节期间!)做的一个RPC框架,现与大家分享. 设计SnakeRPC的主要动机是,Hessian返回的状态对象(如:数据库连接对象.文件对象等)无法复用,而且它对Strea ...

  9. SQL Server 2012 内存管理 (memory management) 改进

    SQL Server 2012 的内存管理和以前的版本相比,有以下的一些变化. 一.内存分配器的变化 SQL Server 2012以前的版本,比如SQL Server 2008 R2等, 有sing ...

  10. Java_Web _Servlet生命周期实验

    第一次加载这个servlet程序时(选择右边的servlet程序,注意servlet程序没有main函数,因此执行的是run as servlet Application ),同时执行init()方法 ...