从 NSDictionary 取值的时候有两个方法,objectForKey: 和 valueForKey:,这两个方法具体有什么不同呢?
先从 NSDictionary 文档中来看这两个方法的定义:
objectForKey: returns the value associated with aKey, or nil if no value is associated with aKey. 返回指定 key 的 value,若没有这个 key 返回 nil.
valueForKey: returns the value associated with a given key. 同样是返回指定 key 的 value。
直观上看这两个方法好像没有什么区别,但文档里 valueForKey: 有额外一点:
If key does not start with “@”, invokes objectForKey:. If key does start with “@”, strips the “@” and invokes [super valueForKey:] with the rest of the key. via Discussion
一般来说 key 可以是任意字符串组合,如果 key 不是以 @ 符号开头,这时候 valueForKey: 等同于 objectForKey:,如果是以 @ 开头,去掉 key 里的 @ 然后用剩下部分作为 key 执行 [super valueForKey:]。
比如:
NSDictionary *dict = [NSDictionary dictionaryWithObject:@"theValue"
forKey:@"theKey"];
NSString *value1 = [dict objectForKey:@"theKey"];
NSString *value2 = [dict valueForKey:@"theKey"];
这时候 value1 和 value2 是一样的结果。如果是这样一个 dict:
NSDictionary *dict = [NSDictionary dictionaryWithObject:@"theValue"
forKey:@"@theKey"];// 注意这个 key 是以 @ 开头
NSString *value1 = [dict objectForKey:@"@theKey"];
NSString *value2 = [dict valueForKey:@"@theKey"];
value1 可以正确取值,但是 value2 取值会直接 crash 掉,报错信息:
Terminating app due to uncaught exception ‘NSUnknownKeyException’, reason: ‘[<__NSCFDictionary 0x892fd80> valueForUndefinedKey:]: this class is not key value coding-compliant for the key theKey.’
这是因为 valueForKey: 是 KVC(NSKeyValueCoding) 的方法,在 KVC 里可以通过 property 同名字符串来获取对应的值。比如:
@interface Person : NSObject
@property (nonatomic, retain) NSString *name;
@end
...
Person *person = [[Person alloc] init];
person.name = @"fannheyward";
NSLog(@"name:%@", [person name]);
//name:fannheyward
NSLog(@"name:%@", [person valueForKey:@"name"]);
//name:fannheyward
[person release];
valueForKey: 取值是找和指定 key 同名的 property accessor,没有的时候执行 valueForUndefinedKey:,而 valueForUndefinedKey: 的默认实现是抛出 NSUndefinedKeyException 异常。
回过头来看刚才 crash 的例子, [dict valueForKey:@"@theKey"]; 会把 key 里的 @ 去掉,也就变成了 [dict valueForKey:@"theKey"];,而 dict 不存在 theKey 这样的 property,转而执行 [dict valueForUndefinedKey:@"theKey"];,抛出 NSUndefinedKeyException 异常后 crash 掉。
objectForKey: 和 valueForKey: 在多数情况下都是一样的结果返回,但是如果 key 是以 @ 开头,valueForKey: 就成了一个大坑,建议在 NSDictionary 下只用 objectForKey: 来取值。
发表评论
-
IOS开发 多线程 一
2013-11-19 11:46 478原文:http://blog.csdn.net/develo ... -
IOS 学习 Key-value coding
2013-11-19 10:56 796原文:http://blog.csdn.net/develo ... -
IOS block dispatch_queue
2012-11-05 15:04 891研究了3天的block使用,今天终于写出了自己的第一个b ... -
socket编程 详解
2012-08-28 08:57 1037对TCP/IP、UDP ... -
iOS ASIHTTPRequest详解 非常强大
2012-08-27 13:20 2380ASIHTTPRequest对CFNetwork API ... -
今天看了ps的简介,决定一定要把它给学会,首先了解一下基础知识
2012-08-22 00:01 7171.位图图像的概念 位图图像使用像素来表示图像,因此也 ... -
SDWebImage使用,图片加载和缓存
2012-07-04 11:44 2398SDWebImage托管在github上。https:/ ... -
coredata 理解
2012-06-15 13:08 1359昨天开始认真的看coredata的用法,今天终于明白的其中的 ... -
#ifndef、#def、#endif说明
2012-06-13 13:43 864你所遇到的这几个 ... -
ios 数据存储的四种常用方式NSKeyedArchiver/NSUserDefaults/Writ
2012-06-13 10:49 1336OK,今天Himi介绍游戏 ... -
AVAudioPlayer 音频播放器 使用 教程
2012-06-05 14:33 1203IOS中有三种播放音频的方式:AVAudioPlaye ... -
使用iOS手势UIGestureRecognizer
2012-06-05 10:10 1199UIKit中包含了UIGestureRecognizer ... -
NSAutoReleasePool
2012-05-28 14:40 748好记性不如烂博客. 今天需要记录的是关于NSAutoR ... -
NSLocalizedString 实现国际化
2012-05-28 11:23 817一、获取系统所支持的国际化信息 在国际化之前,你可以在ip ... -
自定义 UIColor baseView 父类子类方法名 不能重复
2012-05-24 11:04 828原来是因为方法名字重复了,因为baseview的方法名和 ... -
Android图片处理(Matrix,ColorMatrix)
2012-05-22 09:24 846在编程中有时候需要 ... -
symbol(s) not found for architexture i386 路径错误
2012-05-16 09:55 1539昨天这个错误又出现 ... -
symbol(s) not found for architexture i386 报错
2012-05-15 18:40 731我靠啊,今天下午出现了个这个错误,找了好多资料,发现让添加li ... -
symbol(s) not found for architexture i386 报错
2012-05-15 18:40 0我靠啊,今天下午出现了个这个错误,找了好多资料,发现让添加li ... -
推送 证书 联机调试
2012-05-15 15:16 822联机调试出现问题, ...
相关推荐
基于 NSDictionary 的内存缓存,可以识别未保留的值。 特征 线程安全。 检测未使用的对象并删除它们。 在进入背景时删除未使用的对象。 在收到内存警告时删除所有对象。 用法 设置对象 [cache setObject: object...
NSDictionary-Accessors 为NSDictionary键入安全访问器,最好与从JSON解析的字典一起使用。 前: id value = nil;value = [dictionary objectForKey:@"id"];if ([value isKindOfClass:[NSNumber class]]) { model....
NSDictionary * smallDic = [contentDic objectForKey:keyArr[i]]; //获取小字典中得内容 NSString * controllerNameStr = [smallDic objectForKey:@"controllerName"]; //将字符串转化为类名 Class ...
NSDictionary *data1 = [json1 objectFromJSONString]; NSLog(@"json1.a:%@",[data1 objectForKey"a"]); NSLog(@"json1.b:%@",[data1 objectForKey"b"]); [json1 release]; // 如果json有嵌套,即value里有...
NULL 博文链接:https://justsee.iteye.com/blog/2252988
[self getData:nil completion:^(NSDictionary *dict) { self.codeView.code = [dict objectForKey:@"code"]; }]; }]; [self.codeView didChangeVerificationCode:^(NSString *code) { NSLog(@"self.codeView ...
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { [picker dismissViewControllerAnimated:YES completion:^{}]; UIImage *image = ...
return ((CCString*)strings->objectForKey(key))->m_sString; } static std::string getImagePathsByKey(std::string key) { if(imagePaths == NULL) { std::string path = CCFileUtils::sharedFileUtils()->...
为了构建一个设备相关的健,你在健的后面要加上~iphone或者~ipad。 常用字段: 1.获取版本信息: NSDictionary*infoDic = [[NSBundle mainBundle] infoDictionary]; NSString *localVersion = [infoDic objectForKey:@...
- (BOOL)application:(UIApplication*)application ...NSDictionary* remoteNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; 获得推送消息内容。如果remote
缓存好的 WellCached 是一个 NSCache 子类,它提供键控下标、基于时间的键过期和一个... 而且,只要您的密钥符合NSCopying协议,您就可以使用类似 NSDictionary 的键控下标语法: ELAWellCached *cache = [ELAWellCac
将demo中的文件夹Model,View文件夹复制到自己的项目中,并导入头文件: #import "PJRPageScrollingView.h" #import "PJRItems.h" 示例代码: - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:...
- (id)objectForKey:(id)aKey expectedClass:(Class)expectedClass withTransformerClass:(Class)transformerClass; - (id)objectForKey:(id)aKey withTransformerBlock:(JMOTransformerBlock)transformerBlock...
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if (...
SYCache 简单的内存和磁盘缓存。 它由内存中的支持,因此在内存不足时会...如果要在启用了的项目中包括SYCache,则需要在所有SYCache源文件上设置-fno-objc-arc编译器标志。 要在Xcode中执行此操作,请转到活动目标
1、程序未启动(即底部任务栏里没有进程)时: ... - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:...NSDictionary* pushNotificationKey = [launchOptions objectForKey:UI
plist文件是标准的xml文件 A).写入plist文件:(Dictionary/Array) NSMutableDictionary* dict = [ [ NSMutableDictionary alloc ] ...NSString* object = [ dict objectForKey:@"RestartSpringBoard" ];
简单的方法异步写入磁盘在调用dealloc时控制清理磁盘安装有两种方法可以在您的项目中使用它: 将 Diskcached 类文件复制到您的项目中用 CocoaPods 安装编写 Podfile platform :iospod 'Diskcached' , '~> 0.0.1'...
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; if ...
在您的项目中添加行 #import "UIButton+HBHashButton.h" UIButtons 现在可以像 NSMutableDictionary 一样工作 ###例子 UIButton *button = [UIButton alloc]initWithFrame:CGRectMake:(0,0,100,90)]; [button ...