从[id setValue: forKey:]了解KVC
《Objective-C基础教程》 P224页有详细介绍
下边是apple官网的简单介绍 和一个应用的例子。
KVC就是Key-value coding,大意是允许通过一个Key来读写一个value。
最最常见就是
[id setValue: forKey:]
[id valueforKey:]
这两个方法允许你指定一个Key,然后通过这个Key去访问指定对象中的value
- [obj valueforKey:@"name"]; //=>返回:在指定的对象里(obj),去查找名为“name”的实例变量的数值
- [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的更多相关文章
- KVC之-setValue:forKey:方法实现原理与验证
KVC之-setValue:forKey:方法实现原理与验证 - (void)setValue:(id)value forKey:(NSString *)key方法,实现原理与验证 功能:使用一个字符 ...
- iOS.KVC.setValue:forKey:
Foundation Framework 定义了 NSObject(NSKeyValueCoding), - (void)setValue:(id)value forKey:(NSString *)k ...
- setObject:forKey和setValue:forKey的区别
setObject:forKey: 是NSMutableDictionary类的方法 key参数类型可以是任意类型对象 ...
- Objective-c setObject:forKey:和setValue:forKey:的区别
setObject:forKey: 是NSMutableDictionary类的方法 key参数类型可以是任意类型对象 ...
- IOS setValue forKey
NSObjiect *obj:[obj setValue:value forKey:@"cpname"]复制代码的时候都会出现这个异常this class is not key v ...
- iOS NSUserDefaults [setValue:forKey:] [setObject:forKey:] <Objc> setValue(_,forKey:) set(_,forKey) <Swift 3>
前者其实是NSObject都可以调用的KVC方法,后者才是NSUserDefaults的实例方法: 这里参数的类型是nullable id,但是我建议你在传null的时候慎重考虑,否则你的应用就可能面 ...
- - (BOOL)setResourceValue:(id)value forKey:(NSString *)key error:(NSError **)error
如果我们的APP需要存放比较大的文件的时候,同时又不希望被系统清理掉,那我么我们就需要把我们的资源保存在Documents目录下,但是我们又不希望他会被iCloud备份,因此就有了这个方法 [URL ...
- KVC 和 KVO 简单总结
KVC: key value coding,键值编码.是一种通过使用属性的名称(key)来间接访问对象属性的方法.这个方法可以不用通过 setter/getter 方法来访问对象的属性.该方法使用的实 ...
- iOS KVC 和 KVO 区别简单总结
KVC: key value coding,键值编码.是一种通过使用属性的名称(key)来间接访问对象属性的方法.这个方法可以不用通过 setter/getter 方法来访问对象的属性.该方法使用的实 ...
随机推荐
- Linux服务器的16个监控命令
想不想知道你的服务器到底在干什么?那么你要知道本文介绍的这些基本命令.一旦你熟悉掌握了这些命令,就为成为专业的 Linux系统管理员打下了基础. 你可以通过图形化用户界面(GUI)程序来获取这些外壳命 ...
- Vue源码------------- 数据响应系统的基本思路
在 Vue 中,我们可以使用 $watch 观测一个字段,当字段的值发生变化的时候执行指定的观察者,如下: var vm = new Vue({ data: { num:1 } }) vm.$watc ...
- Delphi 虚拟桌面
Delphi创建虚拟桌面实现后台调用外部程序 核心提示:最近在做的一个软件,其中有一部分功能需要调用其它的软件来完成,而那个软件只有可执行文件,根本没有源代码,幸好,我要做的事不难,只需要在我的程序启 ...
- Ajax请求参数为文件类型
1.图片用get请求,回调函数中返回的数据就是流文件(至于是什么流文件还不清楚), 在回调函数中再使用post请求2.JS将文件像form表单一样提交到后台 : https://www.cnblo ...
- 清理Visual Studio解决方案临时文件:Clean Visual Studio Solution Temporary File Build20160418
复制保存到任意文件名.bat,放置在Visual Studio Solution目录下. 当Visual Studio Solution目录过于庞大或打算拷贝移动Visual Studio Solut ...
- C++——指针与数组
1.数组名不是指针,神似指针(可以将数组名直接赋值给指针) (1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组:(2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针 ...
- 【React-Native】---Android环境配置
一.前言 本文主要内容是在Window系统下配置Android APP的开发环境,要配置RN的Android开发环境需要3个依赖 1.JDK(版本必须是 1.8) 2.Node(版本必须高于8.3) ...
- Android Telephony分析(七) ---- 接口扩展(异步转同步)
本文是基于上一篇<Android Telephony分析(六) —- 接口扩展(实践篇)>来写的.上一篇介绍的接口扩展的方法需要实现两部分代码:1. 从APP至RIL,发送请求:2. 从R ...
- VScode Python no module的解决方法
在lauch.json中,修改 "env": {}为 "env": {"PYTHONPATH":"${workspaceRoot} ...
- 牛客网多校训练第八场A All one Matrix
题目链接:https://ac.nowcoder.com/acm/contest/888/A 题意:求出有多少个不被包含的全1子矩阵 解题思路:首先对列做处理,维护每个位置向上1的个数,然后我们从最后 ...