从 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开发之UIlabel多行文字自动换行 (自动折行) UIView *footerView = [[UIView alloc]initWithFrame:CGRectMake(10, 100, 300, 180)]; UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 100, 300, ...
iOS下解析json数据,自己亲自使用过,挺好用的。 使用JSONKit的解析方法:(需导入包:#import "JSONKit/JSONKit.h") - (void)printJson{ //如果json是“单层”的,即value都是字符串、数字,可以使用...
多选视图 IOS基于tableview的多选控件封装,块屏幕 ##使用方法 NSMutableArray *array = [NSMutableArray array];... return [item objectForKey:@"title"]; }]; [self.multiSelect setFlagBlock:^BOOL (id
[cache objectForKey: @" key " ]; 删除未使用的对象 删除未被任何其他对象保留的对象。 [cache removeUnretainedObjects ]; 安装 将ISMemoryCache/ISMemoryCache.{h,m}到您的 Xcode 项目中。 可可豆 如果你使用 ...
简单的方法异步写入磁盘在调用dealloc时控制清理磁盘安装有两种方法可以在您的项目中使用它: 将 Diskcached 类文件复制到您的项目中用 CocoaPods 安装编写 Podfile platform :iospod 'Diskcached' , '~> 0.0.1'...
NSDictionary-Accessors 为NSDictionary键入安全访问器,最好与从JSON解析的字典一起使用。 前: id value = nil;value = [dictionary objectForKey:@"id"];if ([value isKindOfClass:[NSNumber class]]) { model....
self.codeView.code = [dict objectForKey:@"code"]; }]; }]; [self.codeView didChangeVerificationCode:^(NSString *code) { NSLog(@"self.codeView code:%@",code); }]; //开始生成code [self.codeView ...
- (BOOL)application:(UIApplication*)application ...NSDictionary* remoteNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; 获得推送消息内容。如果remote
[queryItemArray addObject:[NSURLQueryItem queryItemWithName:@"version" value:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]]]; [urlComponents setQueryItems:...
1、程序未启动(即底部任务栏里没有进程)时: ... - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:...NSDictionary* pushNotificationKey = [launchOptions objectForKey:UI
NSDictionary * smallDic = [contentDic objectForKey:keyArr[i]]; //获取小字典中得内容 NSString * controllerNameStr = [smallDic objectForKey:@"controllerName"]; //将字符串转化为类名 Class ...
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() ...
- (id)objectForKey:(id)aKey expectedClass:(Class)expectedClass withTransformerClass:(Class)transformerClass; - (id)objectForKey:(id)aKey withTransformerBlock:(JMOTransformerBlock)transformerBlock...
Info.plist用于向iOS提供关于app,bundle或者framework的一些重要信息。它指定了比如一个应用应该怎样启动,它如何被本地化,应用的名称,要显示的图标,...NSString *localVersion = [infoDic objectForKey:@”CFBundl
实例如下所示: ... UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) { UIImageWriteToSavedPhotosAl
return ((CCString*)strings->objectForKey(key))->m_sString; } static std::string getImagePathsByKey(std::string key) { if(imagePaths == NULL) { std::string path = CCFileUtils::sharedFileUtils()->...
TMCache 是 Tumblr 公司开发的一个快速,无死锁的并行对象缓存,支持 iOS 和 OS X 系统。示例代码:UIImage *img = [[UIImage alloc] initWithData:data scale:[[UIScreen mainScreen] scale]];[[PINCache ...
PINCache 是 Pinterest 公司开发的一个快速,无死锁的并行对象缓存,支持 iOS 和 OS X 系统, 是 TMCache 的改进版本。示例代码:UIImage *img = [[UIImage alloc] initWithData:data scale:[[UIScreen mainScreen] ...
IOS 中NSUserDefaults读取和写入自定义对象的实现方法 NSUserDefaults可以存取一些短小的信息。 比如存入再读出一个字符串到NSUserDefaults: NSString *string = [NSString stringWithString @hahaha]; ...