本章将分为三个部分:

  • 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的更多相关文章

  1. KVC & KVO

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

  2. KVC/KVO原理详解及编程指南

    一.简介 1.KVC简介 2.KVO简介 二.KVC相关技术 1.Key和Key Path 2.点语法和KVC 3.一对多关系(To-Many)中的集合访问器方法 4.键值验证(Key-Value V ...

  3. 深入理解 KVC\KVO 实现机制 — KVC

    KVC和KVO都属于键值编程而且底层实现机制都是isa-swizzing,所以本来想放在一起讲的.但是篇幅有限所以就分成了两篇博文 KVO实现机制传送门 KVC概述 KVC是Key Value Cod ...

  4. kvc kvo(摘录)

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

  5. 【转】 KVC/KVO原理详解及编程指南

    原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 前言: 1.本文基本不讲KVC/KVO的用法,只结合网上的资料说说对这种技术的 ...

  6. kvc/kvo复习

    kvc/kvo复习 1 小问题 '[<XMGPerson 0x7fb8a8f30220> setValue:forUndefinedKey:]: this XMGPerson * pers ...

  7. 转:KVC/KVO原理详解及编程指南

      作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或 ...

  8. 阶段性总结⓵触摸事件&手势识别⓶Quartz2D绘图⓷CALayer图层⓸CAAnimation⓹UIDynamic UI动力学⓺KVC&KVO

    知识点复习   1. 触摸事件&手势识别   1> 4个触摸事件,针对视图的 2> 6个手势识别(除了用代码添加,也可以用Storyboard添加)   附加在某一个特定视图上的, ...

  9. IOS开发之KVC KVO KVB

    KVC(Key Value Coding) KVO(Key Value Observing) KVB(Key Value Binding) KVO是Cocoa的一个重要机制,他提供了观察某一属性变化的 ...

随机推荐

  1. asp.net MVC 视图文件(cshtml/vbhtml)变更编译过程示范

    更改cshtml文件的时候 并不会触发程序重新启动,而是进入了编译状态  csc.exe进程启动. 非阻塞的方式进行等待,延时等待. 示范程序:http://pan.baidu.com/s/1skDY ...

  2. CentOS6.5卸载默认安装的mysql5.1,并安装mysql5.5(亲测有效)

    感谢链接:https://jingyan.baidu.com/article/922554465e471a851648f4ed.html  指导. 1.安装前:CentOS6.5 yum 安装MySQ ...

  3. MPEG-4 压缩编码标准

    文章转自:http://www.cnblogs.com/CoderTian/p/8477021.html 1.MPEG-4标准概述 与MPEG1和MPEG2标准相比,MPEG-4 更加注重多媒体系统的 ...

  4. 各种Map的区别,想在Map放入自定义顺序的键值对

    今天做统计时需要对X轴的地区按照地区代码(areaCode)进行排序,由于在构建XMLData使用的map来进行数据统计的,所以在统计过程中就需要对map进行排序. 一.简单介绍Map 在讲解Map排 ...

  5. AutoFac文档14(转载)

    目录 开始 Registering components 控制范围和生命周期 用模块结构化Autofac xml配置 与.net集成 深入理解Autofac 指导 关于 词汇表 激活事件 在compo ...

  6. AutoFac文档9(转载)

    目录 开始 Registering components 控制范围和生命周期 用模块结构化Autofac xml配置 与.net集成 深入理解Autofac 指导 关于 词汇表 关系类型 Autofa ...

  7. Spring IOC和AOP 基础

    1 spring中注入资源是通过描述来实现的,在 spring 中是通过注解或者 XML 描述.spring 中IOC 注入方式有三种 1)构造方法注入 2)setter 注入 3)接口注入 1.1) ...

  8. 如何实现php异步处理

    在实际生成环境下,php作为后台的接口服务器已经很常见,php当然具有它能作为后台服务器的优势之处,但是,在处理一些客户端并不关心的结果时,就显出它的弊端了---没有异步执行的机制.就比如我们想做一些 ...

  9. 坑爹的A标签 href

    A标签 href在与click事件同时响应时,如果click事件有提交表单动作,href会阻拦表单提交,解决 1.去掉href 2.href="javascript:void();" ...

  10. 重置 ckeditor清空内容

    转载自:http://blog.csdn.net/woshirongshaolin/article/details/8239407 <script type="text/javascr ...