it-swarm.com.ru

Разница между objectForKey и valueForKey?

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

341
Devoted

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 .

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

400
Corey Floyd

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

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

63
dreamlax

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

21
Nick Locking

Как уже было сказано, тип данных 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 будет доступно для объекта того же типа.

12
Harjot Singh