最近在项目开发过程中使用NSDictionary取值的过程中,发现并没有关注过objectForKey和valueForKey的差异,而只是一直去使用它们,所以想今天写这个就是为了弄清楚它们的区别
首先我们要明白,objectForKey是NSDictionary的方法,valueForKey是KVC提供的方法。
我们看一下官方文档中的定义:
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。
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去掉@符号后剩下部分作为key值去执行方法
举例:
LPDPerson *person = [[LPDPerson alloc] init];
person.dic = @{@"name":@"dyf"};
NSString *str1 = [person.dic objectForKey:@"name"];
NSString *str2 = [person.dic valueForKey:@"name"];
// person.dic = @{@"@name":@"dyf"};
// NSString *str1 = [person.dic objectForKey:@"@name"];
// NSString *str2 = [person.dic valueForKey:@"@name"];
NSLog(@"str1===%@",str1);
NSLog(@"str2===%@",str2);
看一下日志打印的结果
如果key值是以@开头的,如下
LPDPerson *person = [[LPDPerson alloc] init];
person.dic = @{@"@name":@"dyf"};
NSString *str1 = [person.dic objectForKey:@"@name"];
NSString *str2 = [person.dic valueForKey:@"@name"];
NSLog(@"str1===%@",str1);
NSLog(@"str2===%@",str2);
由于valueForKey在该情况下会忽略@符号,因此找不到key,则报crash,但str1是正常的
回过头来看刚才 crash 的例子, [dict valueForKey:@"@name"]; 会把 key 里的 @ 去掉,也就变成了 [dict valueForKey:@“name”];,而 dict 不存在 theKey 这样的 property,转而执行 [dict valueForUndefinedKey:@“name”];,抛出 NSUndefinedKeyException异常后 crash 掉。
因此,我们在平时使用NSDictionary的时候建议使用objectForKey