从 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:]
。
比如:
1 2 3 4 |
|
这时候 value1
和 value2
是一样的结果。如果是这样一个 dict:
1 2 3 4 |
|
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 同名字符串来获取对应的值。比如:
KVC get property value
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
valueForKey:
取值是找和指定 key 同名的 property accessor,没有的时候执行 valueForUndefinedKey:
,而 valueForUndefinedKey:
的默认实现是抛出 NSUndefinedKeyException
异常。参考Getting Attribute Values Using Key-Value Coding
回过头来看刚才 crash 的例子, [dict valueForKey:@"@theKey"]
(如果不存在这个key,会返回nil,但@"thekey"会返回nil);
会把 key 里的 @ 去掉,也就变成了 [dict valueForKey:@"theKey"];
,而 dict 不存在 theKey
这样的 property,转而执行 [dict valueForUndefinedKey:@"theKey"];
,抛出 NSUndefinedKeyException
异常后 crash 掉。
objectForKey:
和 valueForKey:
在多数情况下都是一样的结果返回,但是如果 key 是以 @ 开头,valueForKey:
就成了一个大坑,建议在 NSDictionary 下只用 objectForKey:
来取值。
给 [dict setValue:nilforKey:@"b"];相当于从字典中删除这个key!
在dict中对于objectForKey:
和 valueForKey:中key不是@开头的且不存在这个key则都返回nil
{ //不存在key@"1"
NSLog(@"%@",[dictionary objectForKey:@"1"]);
NSLog(@"%@",[dictionary valueForKey:@"1"]);
//不存在key@"1"
NSLog(@"%@",[dictionary objectForKey:@"@1"]);
// NSLog(@"%@",[dictionary valueForKey:@"@1"]);//crash
//key无所谓存在
// [dictionary setObject:nil forKey:@"1"];//crash
[dictionary setValue:nil forKey:@"1"];
}
感谢:http://fann.im/blog/2012/04/12/difference-between-objectforkey-and-valueforkey-in-nsdictionary/
ps:另见:《Objective-c 基础教程》P222键/值编码
相关推荐
基于 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 = ...
缓存好的 WellCached 是一个 NSCache 子类,它提供键控下标、基于时间的键过期和一个... 而且,只要您的密钥符合NSCopying协议,您就可以使用类似 NSDictionary 的键控下标语法: ELAWellCached *cache = [ELAWellCac
- (BOOL)application:(UIApplication*)application ...NSDictionary* remoteNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; 获得推送消息内容。如果remote
- (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 (...
NSDictionary *dict = [placeArray objectAtIndex:i]; PJRItems *item = [[PJRItems alloc] init]; item.itemTitle = [dict objectForKey:@"placeName"]; item.itemDesc = [dict objectForKey:@"placeDesc"];...
Info.plist用于向iOS提供关于app,bundle或者framework的一些重要信息。它指定了比如一个应用应该怎样启动,它如何被本地化,应用的名称,要显示的图标,...NSString *localVersion = [infoDic objectForKey:@”CFBundl
1、程序未启动(即底部任务栏里没有进程)时: ... - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:...NSDictionary* pushNotificationKey = [launchOptions objectForKey:UI
return ((CCString*)strings->objectForKey(key))->m_sString; } static std::string getImagePathsByKey(std::string key) { if(imagePaths == NULL) { std::string path = CCFileUtils::sharedFileUtils()->...
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; if ...
plist文件是标准的xml文件 A).写入plist文件:(Dictionary/Array) NSMutableDictionary* dict = [ [ NSMutableDictionary alloc ] ...NSString* object = [ dict objectForKey:@"RestartSpringBoard" ];
Objective-C Json 实例详解 ...Json的顶层可以是{} 或 []因此可以有 NSDictionary 和 NSArray 两种格式。读取使用 ObjectForKey 返回对应的对象。 NSString* items = @{items:[item0,item1,item2]};
- ( void )objectForKey:( NSString *)key usingBlock:( void (^)( id object))block; - ( void )setObject:( id )object forKey:( NSString *)key; 有关方法的完整列表,请参见 。 添加到您的项目 只需将SYCache.h...
// returns immediately[[PINCache sharedCache] objectForKey:@"image" block:^(PINCache *cache, NSString *key, id object) { UIImage *image = (UIImage *)object; NSLog(@"image scale: %f", image.scale);...