Разница между objectForKey и valueForKey? - PullRequest
341 голосов
/ 30 июня 2009

В чем разница между objectForKey и valueForKey?Я посмотрел оба документа в документации, и они показались мне одинаковыми.

Ответы [ 4 ]

401 голосов
/ 30 июня 2009

objectForKey: - это метод NSDictionary. NSDictionary - это класс коллекции, аналогичный NSArray, за исключением того, что вместо использования индексов он использует ключи для различения элементов. Ключ - это произвольная строка, которую вы предоставляете. Никакие два объекта не могут иметь одинаковый ключ (точно так же, как никакие два объекта в NSArray не могут иметь одинаковый индекс).

valueForKey: - это метод KVC. Это работает с любым классом. valueForKey: позволяет получить доступ к свойству, используя строку для его имени. Например, если у меня есть класс Account со свойством accountNumber, я могу сделать следующее:

NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];

[newAccount setAccountNumber:anAccountNUmber];

NSNumber *anotherAccountNumber = [newAccount accountNumber];

Используя KVC, я могу получить динамический доступ к свойству:

NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];

[newAccount setValue:anAccountNumber forKey:@"accountNumber"];

NSNumber *anotherAccountNumber = [newAccount valueForKey:@"accountNumber"];

Это эквивалентные наборы утверждений.

Я знаю, вы думаете: вау, но саркастически. KVC выглядит не так уж и полезно. На самом деле это выглядит "многословно". Но когда вы хотите что-то изменить во время выполнения, вы можете сделать много интересных вещей, которые намного сложнее в других языках (но это выходит за рамки вашего вопроса).

Если вы хотите узнать больше о KVC, есть много учебных пособий, если вы пользуетесь Google, особенно в блоге Скотта Стивенсона . Вы также можете проверить справочник по протоколу NSKeyValueCoding .

Надеюсь, это поможет.

63 голосов
/ 30 июня 2009

Когда вы делаете valueForKey:, вам нужно дать ему NSString, тогда как objectForKey: может взять любой подкласс NSObject в качестве ключа. Это связано с тем, что для кодирования значения ключа ключи всегда являются строками.

Фактически, в документации говорится, что даже когда вы даете valueForKey: NSString, она все равно будет вызывать objectForKey:, если только строка не начинается с @, в этом случае она вызывает [super valueForKey:], что может вызвать valueForUndefinedKey:, что может вызвать исключение.

21 голосов
/ 30 декабря 2013

Вот веская причина использовать objectForKey: везде, где это возможно, вместо valueForKey: - valueForKey: с неизвестным ключом выдает NSUnknownKeyException, говоря «этот класс не соответствует значению ключа для кода».

12 голосов
/ 17 июля 2014

Как уже говорилось, тип данных objectForKey: равен :(id)aKey, тогда как тип данных valueForKey: равен :(NSString *)key.

Например:

 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObject:@"123"],[NSNumber numberWithInteger:5], nil];

 NSLog(@"objectForKey : --- %@",[dict objectForKey:[NSNumber numberWithInteger:5]]);  
    //This will work fine and prints (    123    )  

 NSLog(@"valueForKey  : --- %@",[dict valueForKey:[NSNumber numberWithInteger:5]]); 
    //it gives warning "Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'"   ---- This will crash on runtime. 

Итак, valueForKey: будет принимать только строковое значение и является методом KVC, тогда как objectForKey: будет принимать любой тип объекта.

Значение в objectForKey будет доступно для объекта того же типа.

...