最近在項(xiàng)目開發(fā)過程中使用NSDictionary取值的過程中,發(fā)現(xiàn)并沒有關(guān)注過objectForKey和valueForKey的差異,而只是一直去使用它們,所以想今天寫這個(gè)就是為了弄清楚它們的區(qū)別
首先我們要明白,objectForKey是NSDictionary的方法,valueForKey是KVC提供的方法。
我們看一下官方文檔中的定義:
objectForKey: returns the value associated with aKey, or nil if no value is associated with aKey. 返回指定 key 的 value,若沒有這個(gè) 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
從文檔說明我們就可以看出它們的區(qū)別了。如果key不是以@開頭,則這兩個(gè)方法是等價(jià)的,但如果key以@開頭,valueForKey去掉@符號(hào)后剩下部分作為key值去執(zhí)行方法
舉例:
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);
看一下日志打印的結(jié)果

如果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在該情況下會(huì)忽略@符號(hào),因此找不到key,則報(bào)crash,但str1是正常的

回過頭來看剛才 crash 的例子, [dict valueForKey:@"@name"]; 會(huì)把 key 里的 @ 去掉,也就變成了 [dict valueForKey:@“name”];,而 dict 不存在 theKey 這樣的 property,轉(zhuǎn)而執(zhí)行 [dict valueForUndefinedKey:@“name”];,拋出 NSUndefinedKeyException異常后 crash 掉。
因此,我們?cè)谄綍r(shí)使用NSDictionary的時(shí)候建議使用objectForKey