objectForKey与valueForKey在NSDictionary中的差异
从 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: 来取值。
objectForKey与valueForKey在NSDictionary中的差异的更多相关文章
- IOS开发之——objectForKey与valueForKey在NSDictionary中的差异
从 NSDictionary 取值的时候有两个方法,objectForKey: 和 valueForKey:,这两个方法具体有什么不同呢? 先从 NSDictionary 文档中来看这两个方法的定义: ...
- IOS-objectForKey与valueForKey在NSDictionary中的差异
从 NSDictionary 取值的时候有两个方法,objectForKey: 和 valueForKey:,这两个方法具体有什么不同呢? 先从 NSDictionary 文档中来看这两个方法的定义: ...
- JS Date当前时间:获取日期时间方法在各浏览器中的差异
转自:http://www.feiesoft.com/00047/<script type="text/javascript"> // JS Date当前时间获取方法在 ...
- JMeter下Groovy和BeanShell语言在不同组件中性能差异实践探究
一般而言JMeter下性能最好的是jar包这类java原生请求,对于JMeter并没有原生支持的请求,一般都会将其直接编译为jar包,然后再JMeter中调用,这样性能最好. 但是有些需求并不适合用j ...
- JavaScript在IE浏览器和Firefox浏览器中的差异总结
JavaScript在IE浏览器和Firefox浏览器中存在一些差异,以下对这些差异部分进行了总结,以及解决方案: 1.HTML对象的 id 作为对象名的问题 IE:HTML 对象的 ID 可以作为 ...
- 注意:字符串substring方法在jkd6,7,8中的差异。
标题中的substring方法指的是字符串的substring(int beginIndex, int endIndex)方法,这个方法在jdk6,7是有差异的. substring有什么用? sub ...
- NSArray或NSDictionary中汉字输出
1.问题: NSArray *array = [NSArray arrayWithObjects:@"我",@"在",@"鼓楼", nil] ...
- AF_UNIX和AF_INET域的socket在epoll中的差异
1.AF_UNIX & SOCK_STREAM 1.1 accept_socket BLOCK EPOLLIN|EPOLLET 1.2 accept_socket NON-BLOCK EPOL ...
- js动态加载activeX控件在IE11与低版本IE中的差异
由于IE11更加遵循W3C规范,所以IE11与低版本IE在加载activeX时有差别. 1.IE11中动态加载activeX的顺序 var objectTag = document.createEle ...
随机推荐
- Maven打可执行包的pom.xml配置
单独打出可执行包,然后将依赖包打入lib文件价中 <build> <plugins> <plugin> <groupId>org.apache.mave ...
- python ssh登录
3. 编写linkssh.py #!/usr/bin/env python# -*- coding: utf-8 -*-# filename: pexpect_test.py'''Created on ...
- Jenkins基础复习
- js获取显示器、页面等高度 (转)
网页可见区域宽:document.body.clientWidth网页可见区域高:document.body.clientHeight网页可见区域宽:document.body.offsetWidth ...
- URAL 1830 Help in the RNOS 思路,读题 难度:1
http://acm.timus.ru/problem.aspx?space=1&num=1830 这道题需要理解题目操作的意思, 要更改第i位的状态,第i-1位必须激活为1,0-i-2位必须 ...
- LeetCode OJ:Peeking Iterator(peeking 迭代器)
Given an Iterator class interface with methods: next() and hasNext(), design and implement a Peeking ...
- LabVIEW中使用GPU进行高性能计算
项目中需要使用LabVIEW控制NI FPGA board产生控制信号等,使用GPU对采集的数据进行高性能计算,因此方案之一是用Visual Studio设计基于CUDA的GPU并行计算算法代码,然后 ...
- 不能在具有唯一索引“IX_******”的对象“dbo.****”中插入重复键的行。重复键值为 (110, 372000, 2)。
当尝试插入数据,或者更新某个表的时候出现 不能在具有唯一索引“IX_******”的对象“dbo.****”中插入重复键的行.重复键值为 (110, 372000, 2). 遇到这个问题的时候,请找到 ...
- C++面向对象高级编程(四)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一.Static 二.模板类和模板函数 三.namespace 一.Static 静态成员是“类级别”的,也就是它和类的地位等同,而普通成员是“ ...
- Ubuntu12.04 中文输入法设置
1.ibus输入法 Ubuntu系统安装后已经自带了ibus输入法,在英语环境下默认不启动. 配置ibus自动启动可 以在ubuntu系统菜单上选择System(系统)--- Preferences( ...