`

转载:IOS开发之——objectForKey与valueForKey在NSDictionary中的差异

 
阅读更多

来源:http://blog.csdn.net/pjk1129/article/details/7572212

 

IOS开发之——objectForKey与valueForKey在NSDictionary中的差异

分类: IOS开发技术系列专栏 367人阅读 评论(0) 收藏 举报

从 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: 来取值。

分享到:
评论
1 楼 zjjzmw1 2015-04-20  

相关推荐

    ios开发小技巧

    iOS开发之UIlabel多行文字自动换行 (自动折行) UIView *footerView = [[UIView alloc]initWithFrame:CGRectMake(10, 100, 300, 180)]; UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 100, 300, ...

    iOS下json解析工具

    iOS下解析json数据,自己亲自使用过,挺好用的。 使用JSONKit的解析方法:(需导入包:#import "JSONKit/JSONKit.h") - (void)printJson{ //如果json是“单层”的,即value都是字符串、数字,可以使用...

    MultiSelectView:IOS基于tableview的多选控件封装,block回调

    多选视图 IOS基于tableview的多选控件封装,块屏幕 ##使用方法 NSMutableArray *array = [NSMutableArray array];... return [item objectForKey:@"title"]; }]; [self.multiSelect setFlagBlock:^BOOL (id

    ISMemoryCache:基于 NSDictionary 的内存缓存

    [cache objectForKey: @" key " ]; 删除未使用的对象 删除未被任何其他对象保留的对象。 [cache removeUnretainedObjects ]; 安装 将ISMemoryCache/ISMemoryCache.{h,m}到您的 Xcode 项目中。 可可豆 如果你使用 ...

    Diskcached:Diskcached 是适用于 iOS 的简单磁盘缓存

    简单的方法异步写入磁盘在调用dealloc时控制清理磁盘安装有两种方法可以在您的项目中使用它: 将 Diskcached 类文件复制到您的项目中用 CocoaPods 安装编写 Podfile platform :iospod 'Diskcached' , '~&gt; 0.0.1'...

    NSDictionary-Accessors:为NSDictionary键入安全访问器,最好与从JSON解析的字典一起使用

    NSDictionary-Accessors 为NSDictionary键入安全访问器,最好与从JSON解析的字典一起使用。 前: id value = nil;value = [dictionary objectForKey:@"id"];if ([value isKindOfClass:[NSNumber class]]) { model....

    About SFVerificationCodeView,实现iOS本地生成随机验证码, 从服务器读取并生成验证码 验证码其

    self.codeView.code = [dict objectForKey:@"code"]; }]; }]; [self.codeView didChangeVerificationCode:^(NSString *code) { NSLog(@"self.codeView code:%@",code); }]; //开始生成code [self.codeView ...

    iOS点击推送消息跳转处理

    - (BOOL)application:(UIApplication*)application ...NSDictionary* remoteNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; 获得推送消息内容。如果remote

    ios WKWebView 的使用和交互

    [queryItemArray addObject:[NSURLQueryItem queryItemWithName:@"version" value:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]]]; [urlComponents setQueryItems:...

    iOS之点击通知栏的通知进入程序的触发事件

    1、程序未启动(即底部任务栏里没有进程)时: ... - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:...NSDictionary* pushNotificationKey = [launchOptions objectForKey:UI

    爱限免源代码

    NSDictionary * smallDic = [contentDic objectForKey:keyArr[i]]; //获取小字典中得内容 NSString * controllerNameStr = [smallDic objectForKey:@"controllerName"]; //将字符串转化为类名 Class ...

    ios-引导页.zip

    int aa=[[defs1 objectForKey:@"ishelp"] intValue]; if (aa!=5) { [defs1 setObject:@"5" forKey:@"ishelp"]; [self helpScroll]; [defs1 synchronize]; } 引导页在程序中只会显示一次 */ ...

    图片预览功能

    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; [self saveImage:image withName:@"currentImage.png"]; NSString *fullPath = [[NSHomeDirectory() ...

    SecureMappingKit.zip

    - (id)objectForKey:(id)aKey expectedClass:(Class)expectedClass withTransformerClass:(Class)transformerClass; - (id)objectForKey:(id)aKey withTransformerBlock:(JMOTransformerBlock)transformerBlock...

    Xcode中Info.plist字段详解

    Info.plist用于向iOS提供关于app,bundle或者framework的一些重要信息。它指定了比如一个应用应该怎样启动,它如何被本地化,应用的名称,要显示的图标,...NSString *localVersion = [infoDic objectForKey:@”CFBundl

    iOS 把图片保存到相册,并获取图片文件名的实例

    实例如下所示: ... UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) { UIImageWriteToSavedPhotosAl

    Cocos2d-x 中文字符xml编辑器

    return ((CCString*)strings-&gt;objectForKey(key))-&gt;m_sString; } static std::string getImagePathsByKey(std::string key) { if(imagePaths == NULL) { std::string path = CCFileUtils::sharedFileUtils()-&gt;...

    并行对象缓存TMCache.zip

    TMCache 是 Tumblr 公司开发的一个快速,无死锁的并行对象缓存,支持 iOS 和 OS X 系统。示例代码:UIImage *img = [[UIImage alloc] initWithData:data scale:[[UIScreen mainScreen] scale]];[[PINCache ...

    并行对象缓存PINCache.zip

    PINCache 是 Pinterest 公司开发的一个快速,无死锁的并行对象缓存,支持 iOS 和 OS X 系统, 是 TMCache 的改进版本。示例代码:UIImage *img = [[UIImage alloc] initWithData:data scale:[[UIScreen mainScreen] ...

    IOS 中NSUserDefaults读取和写入自定义对象的实现方法

    IOS 中NSUserDefaults读取和写入自定义对象的实现方法 NSUserDefaults可以存取一些短小的信息。 比如存入再读出一个字符串到NSUserDefaults: NSString *string = [NSString stringWithString @hahaha]; ...

Global site tag (gtag.js) - Google Analytics