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

最新文章

  1. 基于本地存储的kvm虚拟机在线迁移
  2. Types of CQRS
  3. asp.net mvc 过滤器
  4. 用 pyvenv 创建几个不相互影响的python虚拟环境
  5. flume-ng 集群搭脚本
  6. phpcms V9 首页模板文件解析
  7. 20个超实用的JavaScript技巧及最佳实践
  8. canvas-js贝塞尔曲线代码在线生成工具
  9. HDU 3308 LCIS (线段树区间合并)
  10. Shell 脚本模拟 milter 实现黑白名单及关键词过滤
  11. Hihocode 1015 KMP算法
  12. RADIUS and IPv6[frc-3162译文]
  13. jQuery选择器使用习惯
  14. UOJ#335. 【清华集训2017】生成树计数 多项式,FFT,下降幂,分治
  15. 剑指offer【01】- 二维数组中的查找(Java)
  16. go中redis使用小结
  17. Excel2007VBA数组和工作表及单元格的引用
  18. 论文中“but”与“however”的区别
  19. C++ 定时器任务类实现
  20. Material Design系列第一篇——Creating Apps with Material Design

热门文章

  1. Objective-C中NSArray和NSMutableArray是如何使用的?
  2. hadoop学习记录(零)
  3. Linux批量替换文件内容
  4. Android 自学之自动完成文本框 AutoCompleteTextView
  5. 【二分答案+贪心】解决“最小值最大”问题(UVa 12124 - Assemble)
  6. 基于Selenium2+Java的UI自动化(1) - 原理和环境搭建
  7. JavaScript高级程序设计(第三版)学习,第一次总结
  8. ASP中双引号单引号和&amp;连接符使用技巧
  9. SQL Server高级内容之表表达式和复习
  10. java包和jar包