本章将分为三个部分:

  • 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. 关于RHEL6下桥网配置的写法(ifcfg-eth0,ifcfg-br0) / 在阿里云的CentOS上安装docker

    Posted on 2011-07-28 16:46 zhousir1991 阅读(1978) 评论(0) 编辑 收藏 以下仅仅是我在做练习的时候下的环境,参照写即可:  [root@desktop2 ...

  2. iOS_数据库2_基础知识

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5lbnQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  3. List、Set、Map常见集合遍历总结

    Java中的集合有三大类,List.Set.Map,都处于java.util包中,List.Set和Map都是接口,不能被实例化,它们的各自的实现类可以被实例化.List的实现类主要有ArrayLis ...

  4. map 类简介和例程

    一.标准库的map类型 使用map得包含map类所在的头文件 template < class Key, class Type, class Traits = less<Key>, ...

  5. Linux环境进程间通信(一)

    1. 管道概述及相关API应用 1.1 管道相关的关键概念 管道是Linux支持的最初Unix IPC形式之中的一个.具有下面特点: 管道是半双工的,数据仅仅能向一个方向流动.须要两方通信时.须要建立 ...

  6. opensips编译安装时可能遇到的问题

    错误一: ERROR: could not load the script in /usr/local//lib64/opensips/opensipsctl/opensipsdbctl.pgsql ...

  7. Spring Cloud(四):熔断器Hystrix

    熔断器 雪崩效应 在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应.服务雪崩效应是一种因“服务提供者”的不可用导致“服务 ...

  8. [Jobdu] 题目1455:珍惜现在,感恩生活

    题目描述: 为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买.请问:你用有限的资金最 ...

  9. Typeface-为自定义字体提供字体内存缓存

    Android 上自定义字体的代码一般如下: TextView textview = (TextView) findViewById(R.id.your_referenced_textview); / ...

  10. 基于 html5的 jquery 轮播插件 flickerplate

    https://github.com/chrishumboldt/Flickerplate 官网 <link href="${baseURL}/themes/default/css/f ...