《Objective-C基础教程》 P224页有详细介绍

下边是apple官网的简单介绍 和一个应用的例子。

KVC就是Key-value coding,大意是允许通过一个Key来读写一个value。

最最常见就是

[id setValue: forKey:]

[id  valueforKey:]

这两个方法允许你指定一个Key,然后通过这个Key去访问指定对象中的value

  1. [obj  valueforKey:@"name"];          //=>返回:在指定的对象里(obj),去查找名为“name”的实例变量的数值
  2. [obj  setValue:@"target" forKey:@"name"]    //=>在obj中,将名为name的实例变量的数值,更换为“target”

KVC是去调用@synthesize,所以对应的name应该是名为name或_name的实例变量才对

和键-值编码方法一样,自动的键-值观察将遵循键-值的访问器作出的变更通知给观察者。表1中的例子可实现当属性name发生变更时,其所有观察者都收到变更通知。

表1 调用键-值观察的方法

// calling the accessor method
[self setName:@"Savings"];
 
// using setValue:forKey:
[self setValue:@"Savings" forKey:@"name"];
 
// using a key path, where account is a kvc-compliant property
// of "document"
[document setValue:@"Savings" forKeyPath:@"account.name"]

自动通知还支持mutableArrayValueForKey:mutableSetValueForKey:返回集合代理对象。这个功能可用于支持insertObject:in<Key>AtIndex:replaceObjectIn<Key>AtIndex:removeObjectFrom<Key>AtIndex:等索引存取方法的对多关系。

你可以通过实现类方法automaticallyNotifiesObserversForKey:来控制你的子类的自动观察通知 。子类可以检测参数检测的键值,并在自动通知可用时返回YES ,禁用时则返回NO

Key-value coding(KVC)机制允许set(设置)和get(获取)变量值。这里的变量名可能是一个字符串,也就是Key。   例如,类Company拥有一个类型为NSString,叫做companyName的变量。  



@interface Company : NSObject

{

    NSString *companyName;

}

 我们就可以这样设置和获取Company实例的companyName值: 



//设置值

Company *company = [[Company alloc] init];

[company setValue:@"Apple" forkey:@"companyName"];

 

//获取值

NSString *x = [company valueForKey:@"companyName"];

 setValue:forKey和valueForKey:的方法在NSObject中有定义。实例 创建名为KVCFun的项目,新建名为AppController的Objective-C Class文件。 AppController.h和AppController.m的代码分别如下: 



#import <Foundation/Foundation.h>

 

@interface AppController : NSObject {

@private

    int fido;

 

}

 

- (int) fido;

- (void) setFido:(int) x;

 

- (IBAction) incrementFido: (id)sender;

 

@end

 



#import "AppController.h"

 

 

@implementation AppController

 

- (id)init

{

    self = [super init];

    if (self) {

        //设置Key

        [self setValue:[NSNumber numberWithInt:5]

                forKey:@"fido"];

 

        NSNumber *n = [self valueForKey:@"fido"];

        NSLog(@"fido = %@", n);

 

    }

 

    return self;

}

 

- (int) fido

{

    NSLog(@"-fido is returning %d", fido);

    return fido;

}

 

- (void) setFido:(int) x

{

    NSLog(@"-setFido is called with %d", x);

    fido = x;

}

 

- (IBAction) incrementFido:(id)sender

{

    //当直接修改值时,通知观察者

    [self willChangeValueForKey:@"fido"];

    fido++;

    NSLog(@"fido is now %d", fido);

    [self didChangeValueForKey:@"fido"];

}

 

- (void)dealloc

{

    [super dealloc];

}

 

@end

 打开MainMenu.nib,添加一个Slider、一个Label、一个Button控件,如下图:  将Slider的Attributes Inspector->Control->State设为“连续的”,再把Binding Inspector->value邦定到AppController实例的fido key上。 将Label也邦定到AppController上,Model Key Path设为fido。 Button链接到incrementFido:action上。  @property和@synthesize
我们可以使用property来代替fido和setFido,并且使用synthesize来实现存取方法。 

使用下面的代码替换AppController.h中的fido和setFido: 



@property (readwrite, assign) int fido;

 使用@synthesize来替换fido和setFido,程序可以正常运行。

从[id setValue: forKey:]了解KVC的更多相关文章

  1. KVC之-setValue:forKey:方法实现原理与验证

    KVC之-setValue:forKey:方法实现原理与验证 - (void)setValue:(id)value forKey:(NSString *)key方法,实现原理与验证 功能:使用一个字符 ...

  2. iOS.KVC.setValue:forKey:

    Foundation Framework 定义了 NSObject(NSKeyValueCoding), - (void)setValue:(id)value forKey:(NSString *)k ...

  3. setObject:forKey和setValue:forKey的区别

    setObject:forKey: 是NSMutableDictionary类的方法                              key参数类型可以是任意类型对象             ...

  4. Objective-c setObject:forKey:和setValue:forKey:的区别

    setObject:forKey: 是NSMutableDictionary类的方法                               key参数类型可以是任意类型对象           ...

  5. IOS setValue forKey

    NSObjiect *obj:[obj setValue:value forKey:@"cpname"]复制代码的时候都会出现这个异常this class is not key v ...

  6. iOS NSUserDefaults [setValue:forKey:] [setObject:forKey:] <Objc> setValue(_,forKey:) set(_,forKey) <Swift 3>

    前者其实是NSObject都可以调用的KVC方法,后者才是NSUserDefaults的实例方法: 这里参数的类型是nullable id,但是我建议你在传null的时候慎重考虑,否则你的应用就可能面 ...

  7. - (BOOL)setResourceValue:(id)value forKey:(NSString *)key error:(NSError **)error

    如果我们的APP需要存放比较大的文件的时候,同时又不希望被系统清理掉,那我么我们就需要把我们的资源保存在Documents目录下,但是我们又不希望他会被iCloud备份,因此就有了这个方法 [URL ...

  8. KVC 和 KVO 简单总结

    KVC: key value coding,键值编码.是一种通过使用属性的名称(key)来间接访问对象属性的方法.这个方法可以不用通过 setter/getter 方法来访问对象的属性.该方法使用的实 ...

  9. iOS KVC 和 KVO 区别简单总结

    KVC: key value coding,键值编码.是一种通过使用属性的名称(key)来间接访问对象属性的方法.这个方法可以不用通过 setter/getter 方法来访问对象的属性.该方法使用的实 ...

随机推荐

  1. 后端异步接口url

    /wp-common/products.php?term_id=4&page=1 var currentAjax; var total = 0; function getAjaxData(te ...

  2. cmake README.TXT

    { cmake .//在当前路径下构建项目 cmake --build .//在当前路径下生成项目(默认为debug)//cmake --build . --config release//在当前路径 ...

  3. session控制登入权限

    <?php session_start(); if(empty($_SESSION["uid"]))//判断SESSION是不是为空 { header("locat ...

  4. Ubuntu下终端命令安装sublime

    Ubuntu下终端命令安装sublime出现软件包无法定位 sublime-text-install 且多次换源不成功 建议采用离线安装 安装教程如下 用Ubuntu上的浏览器下载一个 Sublime ...

  5. 执行 systemctl start firewalld 命令后出现Failed to start firewalld.service: Unit is masked

    firewalld服务被锁定,不能添加对应端口 执行命令,即可实现取消服务的锁定 # systemctl unmask firewalld 下次需要锁定该服务时执行 # systemctl mask ...

  6. elementUI拿到当前表格行的数据的另一种写法

    背景: 这里是通过点击“修改”按钮后才拿到当前行的数据,不是点击当前行任意位置拿到数据,所以不能用 @row-click 方法 改用点击的时候直接拿到这个表里面的这一条数据 1.绑定事件 <te ...

  7. [7.18NOIP模拟测试5]砍树 题解(数论分块)

    题面(加密) 又考没学的姿势……不带这么玩的…… 考场上打了个模拟 骗到30分滚粗了 稍加思考(滑稽)可将题面转化为: 求一个最大的$d$,使得 $\sum \limits _{i=1}^n {(\l ...

  8. spring aop的前奏,动态代理 (5)

    目录 一.先看一个计算器的抽取和实现 二.使用动态代理解决以上问题. 1 设计原理 2 代码实现 2.1 接口代码 2.2 实现接口的代码 2.3 测试代码 2.3 创建动态代理类 2.4 动态代理类 ...

  9. php开发面试题---数据库SQL调优的几种方式

    php开发面试题---数据库SQL调优的几种方式 一.总结 一句话总结: 创建索引:尽量避免使用or或者like,或者sql中的正则 存储查询中间结果 可以加sphinx搜索技术 查询优化 主从数据库 ...

  10. PHP面试 PHP基础知识 六(正则表达式)

    正则表达式 正则表达式的作用 分割.查找.匹配.替换字符串 分隔符:正斜线(/).hash符号(#).以及取反符号(~)   通用原子:\d(代表十进制的0-9).\D (取反除了0-9).\w(数字 ...