KVC/KVO之暴力的KVC
本章将分为三个部分:
- KVC是什么
 - KVC之Set/Get
 - KVC键值路径之Set/Get
 
KVC是什么
KVC,即 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性,并不需要调用setter/getter函数或者类的实例变量。
KVC之Set/Get
类A中有3个变量,都是private权限,关于访问权限的,请参见《Objective-C 成员变量》
A.h
@interface A : NSObject
{
@private
NSString *str;
NSInteger value; //注意这里没星号哦哦哦
NSArray *array;
}
@end
A.m:重写Description函数,用于NSLog
@implementation A
/**
* 重写Description方法,可用于NSLog打印
*/
- (NSString *)description
{
return [NSString stringWithFormat:@"\n%@\n%li\n%@", str, (long)value, array];
}
@end
Main.m:理论上来说,外部变量是访问不到这3个私有变量的,但是暴力的KVC来了。
A *a = [[A alloc] init]; //KVC之set
[a setValue:@"HelloWorld" forKey:@"str"];
[a setValue:@ forKey:@"value"];
[a setValue:@[@"HearthStone", @] forKey:@"array"]; NSLog(@"%@", a); //KVC之get
NSString *str = [a valueForKey:@"str"];
NSInteger value = [[a valueForKey:@"value"] integerValue]; //id 转为 NSInteger
NSArray *array = [a valueForKey:@"array"]; NSLog(@"\n%@\n%ld\n%@", str, (long)value, array);
输出为
HelloWorld
2015
(
    HearthStone,
    2
)
HelloWorld
2015
(
    HearthStone,
    2
)
分析:
KVC的Set方法(重点)
[a setValue:@"HelloWorld" forKey:@"str"];
是KVC的set方法,其中key一定要为消息接收者的属性名称,而不能是自定义的。
KVC的Get方法(重点)
NSString *str = [a valueForKey:@"str"];
是KVC的get方法,其中key一定要为消息接收者的属性名称,而不能是自定义的。
当Set方法遇到基本数据类型
[a setValue:@ forKey:@"value"];
NSInteger是基本数据类型,设置基本数据类型的时候,需要将基本类型转化成NSNumber,在设置值的时候,系统会有自动解包的过程,NSNumber会解包赋值给value.
当Get方法遇到基本数据类型
NSInteger value = [[a valueForKey:@"value"] integerValue]; //id 转为 NSInteger
valueForKey返回的是id类型,id转换为NSInteger的方法应该是上面这种,而下面这种写法是错误的!
NSInteger value = (NSInteger)[a valueForKey:@"value"];
题外话:重写Description来方便NSLog的输出
- (NSString *)description
{
return [NSString stringWithFormat:@"\n%@\n%li\n%@", str, (long)value, array];
} NSLog(@"%@", a);
将打印出
HelloWorld
2015
(
    HearthStone,
    2
)
KVC键值路径之Set/Get
假如A含有一个类B,那么如何通过KVC拿到B的属性呢?答案是使用键值路径。
A.h
@interface A : NSObject
{
@private
NSString *str;
NSInteger value; //注意这里没星号哦哦哦
NSArray *array;
B *b;
}
@end
B.h
@interface B : NSObject
{
@private
NSinteger *age;
}
@end
现在,假如A的array里面装的都是B(装B--)
Main.m
A *a = [[A alloc] init];
...//set Object
[a setValue:@ forKeyPath:@"b.age"]; NSArray *array = [a valueForKeyPath:@"array.age"]; //返回了数组中所有B的age
NSInteger count = [a valueForKeyPath:@"array.@count"]; //返回了数组中B的个数
NSInteger maxAge = [a valueForKeyPath:@"array.@max.age"]; //返回了数组中B的age最大的
NSInteger sumAge = [a valueForKeyPath:@"array.@sum.age"]; //返回了数组中B的age和
NSInteger avgAge = [a valueForKeyPath:@"array.@avg.age"]; //返回了数组中B的age平均值
键值路径可以用来访问不是基本类型的实例变量的属性,也可以快速取到数组中的对象的同一个属性,同时可以利用@count @max @sum @avg等进行计算。
KVC的键值路径的Set方法(重点)
[a setValue:@ forKeyPath:@"b.age"];
KVC的键值路径的Get方法(重点)
NSArray *array = [a valueForKeyPath:@"array.age"]; //返回了数组中所有B的age
KVC/KVO之暴力的KVC的更多相关文章
- KVC & KVO
		
KVC和KVO看上去又是两个挺牛的单词简写,KVC是Key-Value Coding的简写,是键值编码的意思.KVO是Key-Value Observing的简写,是键值观察的意思.那么我们能拿KV ...
 - KVC/KVO原理详解及编程指南
		
一.简介 1.KVC简介 2.KVO简介 二.KVC相关技术 1.Key和Key Path 2.点语法和KVC 3.一对多关系(To-Many)中的集合访问器方法 4.键值验证(Key-Value V ...
 - 深入理解 KVC\KVO 实现机制 — KVC
		
KVC和KVO都属于键值编程而且底层实现机制都是isa-swizzing,所以本来想放在一起讲的.但是篇幅有限所以就分成了两篇博文 KVO实现机制传送门 KVC概述 KVC是Key Value Cod ...
 - kvc kvo(摘录)
		
概述 由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby.Python的动态特性,例如动态类型.动态加载.动态绑定等.今天我们着重介绍ObjC中的键值编码(KVC).键值监听( ...
 - 【转】 KVC/KVO原理详解及编程指南
		
原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 前言: 1.本文基本不讲KVC/KVO的用法,只结合网上的资料说说对这种技术的 ...
 - kvc/kvo复习
		
kvc/kvo复习 1 小问题 '[<XMGPerson 0x7fb8a8f30220> setValue:forUndefinedKey:]: this XMGPerson * pers ...
 - 转:KVC/KVO原理详解及编程指南
		
作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或 ...
 - 阶段性总结⓵触摸事件&手势识别⓶Quartz2D绘图⓷CALayer图层⓸CAAnimation⓹UIDynamic UI动力学⓺KVC&KVO
		
知识点复习 1. 触摸事件&手势识别 1> 4个触摸事件,针对视图的 2> 6个手势识别(除了用代码添加,也可以用Storyboard添加) 附加在某一个特定视图上的, ...
 - IOS开发之KVC KVO KVB
		
KVC(Key Value Coding) KVO(Key Value Observing) KVB(Key Value Binding) KVO是Cocoa的一个重要机制,他提供了观察某一属性变化的 ...
 
随机推荐
- 〖Android〗把CM(Android)源代码导入eclipse的正确方法(2013-7-3)
			
1. 首先应当使CM代码成功编译过一次: cd /path/to/cm . build/envsetup lunch full-eng mka 2. 配置eclipse开发的基本环境 cd /path ...
 - C#日期格式化英文月份   VS改大小写的快捷键
			
DateTime.Now.ToString("MMM yyyyy",CultureInfo.CreateSpecificCulture("en-GB")) ; ...
 - Android  EditText 赋值与取值
			
//取值 String strSmsPhone=m_txtSmsPhone.getText().toString(); //赋值 m_txtSmsPhone.setText("你好" ...
 - Lintcode---翻转二叉树
			
翻转一棵二叉树 您在真实的面试中是否遇到过这个题? Yes 样例 1 1 / \ / \ 2 3 => 3 2 / \ 4 4 思路:依旧采用递归的思路,判断特殊条件后,先交换根节点的左右孩子, ...
 - hadoop+spark集群搭建入门
			
忽略元数据末尾 回到原数据开始处 Hadoop+spark集群搭建 说明: 本文档主要讲述hadoop+spark的集群搭建,linux环境是centos,本文档集群搭建使用两个节点作为集群环境:一个 ...
 - 【打CF,学算法——二星级】Codeforces Round #313 (Div. 2) B. Gerald is into Art(水题)
			
[CF简单介绍] 提交链接:http://codeforces.com/contest/560/problem/B 题面: B. Gerald is into Art time limit per t ...
 - 连接SQLServer的增删改查方法代码
			
在Visual C++中用ADO进行数据库编程 1. 生成应用程序框架并初始化OLE/COM库环境 创建一个标准的MFC AppWizard(exe)应用程序CADOConnection,然后在使用A ...
 - API Management Architecture Notes
			
Kong/Tyk/Zuul/strongloop/Ambassador/Gravitee IBM Reference Architecture for API Management: https:// ...
 - 导出word功能,用html代码在word中插入分页符
			
<span lang=EN-US style="font-size:10.5pt;mso-bidi-font-size:12.0pt;font-family:" mce_st ...
 - ehcache 在集群环境下 出现 Cause was not due to an IOException or NotBoundException
			
RMI 远程调用地址不正确导致 <?xml version="1.0" encoding="UTF-8"?> <ehcache> < ...