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

时间: 2024-12-29 05:07:54

objectForKey与valueForKey在NSDictionary中的差异的相关文章

IOS开发之——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: ret

IOS開發之——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: ret

IOS-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: ret

十二:objectForKey与valueForKey区别简单分析

从 NSDictionary 取值的时候有两个方法,objectForKey: 和 valueForKey:,这两个方法具体有什么不同呢? 以实例说明: 1 NSDictionary *dict = [NSDictionary dictionaryWithObject:@"theValue"forKey:@"theKey"]; 2 NSString *value1 = [dict objectForKey:@"theKey"]; 3 NSStri

在Hyper-V虚拟机中创建差异磁盘克隆系统

Hyper-V虚拟机差异磁盘克隆系统 1.  首先去掉模板的SID值,这里用2003来举例,在2003的安装盘中拷贝这个两个文件到桌面或者C盘 2.  执行其中的sysprep.exe文件,如图 等关机之后在把VHD磁盘拷贝到另外位置,这个拷贝的文件就是你差异磁盘的文件 3.  在Hyper-V服务器上面选择新建磁盘,在新建磁盘类型中选择差异 4.  在指定名称和位置这里写上你名称和位置 5.  给查差异磁盘指定父盘,父盘就是刚才关机之后拷贝的那个文件 然后选择下一步,点击完成,差异磁盘就算创建

java 比对2个相同结构表中的差异数据

项目有需求,比对2个相同结构表中的差异数据. 思路: 1. 分页查询 主库 需要比对的表字段,CONCAT 拼接所有字段 . 2. 用 主库 查询出来的所有ID in 从库ID. 3. 得到2个list,转换为ID为Key的MAP,得到2个MAP. 4.for 2个map.先比对ID是否存在.如不存在.比对 CONCAT 拼接所有字段. 5.如果从库不存在,查询主库insert从库. 测试10W的数据耗时50s. 原文地址:https://www.cnblogs.com/baobaoxiaoke

Vue 2.x 在 Weex 和 Web 中的差异

平台差异 Vue.js 最初是为 Web 平台设计的,虽然可以基于 Weex 开发原生应用,但是 Web 开发和原生开发毕竟不同,在功能和开发体验上都有一些差异,这些差异从本质上讲是原生开发平台和 Web 平台之间的差异,可以通过<Weex 和 Web 平台的差异>了解更多细节和原因. 由于运行平台存在差异,Weex 不支持 Vue 中与 DOM 相关的功能: 不支持事件冒泡和捕获机制,.prevent ..capture ..stop ..self 等事件修饰符在原生环境中无意义. 键盘事件

用javascript编写(找出两个数组中的差异元素并存入一个新的数组,假设每个数组内部都没有重复元素)。

onload = function(){                var a = [2,5,7,9];                var b = [3,4,5,7,8];                                //先准备一个函数,用来检查一个数组中是否包含某个数据,是就返回true,不包含就返回false                //再循环任意一个数组(这里就选a),把该数组中的每一个元素都去b数组中检查,没有就属于差异元素,就存入新的数组        

JavaScript在IE浏览器和Firefox浏览器中的差异总结

window.event对象差异 IE:有window.event对象 FF:没有window.event对象.可以通过给函数的参数传递event对象.如onmousemove=doMouseMove(event) 获取鼠标当前坐标 IE:event.x和event.y. FF:event.pageX和event.pageY. 通用:两者都有event.clientX和event.clientY属性. 鼠标当前坐标(加上滚动条滚过的距离) IE:event.offsetX和event.offse