В чем разница между valueforKey :, objectForKey: и valueForKeyPath :? - PullRequest
34 голосов
/ 20 декабря 2010

У меня есть 2 вопроса:

  1. В чем разница между valueForKey: и objectForKey:?Это для одного NSDictionary с (objectForKey:), а для других - valueforKey: или наоборот?

  2. И в чем разница между * 1014?* а valueForKeyPath:?Это как-то связано с Core Data?

Пожалуйста, помогите.

Ответы [ 3 ]

61 голосов
/ 20 декабря 2010

valueForKey: является частью протокола NSKeyValueCoding и, следовательно, является частью структуры кодирования ключ-значение, которая позволяет получить доступ к свойствам класса по имени во время выполнения.Вот как загружаются, например, NIB - загружаются имена свойств, связанных с соединениями, а затем значения устанавливаются непосредственно по имени.Это отличается от способа, которым инструменты визуального дизайна интерфейса часто работают на других языках, генерируя множество скрытого статически скомпилированного кода.

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

Таким образом, valueForKey: можно использовать в NSDictionary для возврата мета-информации о словаре, например, количества объектов внутри него, спискавсе ключи и т. д. objectForKey: будет фактически использоваться для поиска в словаре.

Во время выполнения разница состоит в том, что objectForKey: - это метод с полностью непрозрачной реализацией.valueForKey: явно полагается на последующий вызов именованных методов получения и установки.Причина последнего заключается в том, что вы можете расширить кодирование значения ключа для наблюдения значения ключа, где вы просите получать информацию каждый раз, когда изменяется конкретное свойство конкретного объекта.Во время выполнения это достигается с помощью метода swizzle, где исходный установщик заменяется новым, который вызывает предыдущий установщик, а затем отправляет необходимые сообщения.Поскольку все сообщения отправляются динамически, это достигается только путем изменения таблиц в экземпляре объекта.

Таким образом, любой объект, совместимый с кодированием значения ключа (это означает, что вы просто объявляете и реализуете свои свойства надлежащим образом, чтоСинтаксис new-ish @ property / @ synthesize делает автоматически) можно наблюдать без необходимости реализации какого-либо кода самим объектом.

Есть и другие вещи Apple, использующие кодирование значения ключа для достижения различных целей, включая CoreData, ноэто не специально для включения какой-либо другой технологии.

valueForKeyPath: похож на valueForKey: за исключением того, что он может проходить несколько объектов.Таким образом, у вас может быть корневой объект с кучей свойств, каждое из которых является другим объектом с другим набором свойств и т. Д., И, используя ключевой путь, вы можете получить выход значения на листе этой структуры данных, вместо того, чтобы иметьитерировать объект за объектом для себя.

В итоге, valueForKey: и valueForKeyPath: предоставляют информацию об экземплярах объекта и взаимодействуют с динамической природой среды выполнения Objective-C.objectForKey: - это специфический для словаря метод, который выполняет словарные задачи.

Дополнения:

Пример, закодированный как I-тип и предполагающий, что NSDictionary совместим с кодированием значения ключа:

NSDictionary *someDictionary;
// create someDictionary, populate it, for example (note: we assume photoOfKeys.jpg
// definitely exists, not a good idea for production code — if it doesn't we'll get
// a nil there and anything after it won't be added to the dictionary as it'll appear
// that we terminated the list):
someDictionary = @{ @"favouriteGarment": @"hat",
                    @"@allKeys"        : [NSImage imageNamed:NSImageNameDotMac],
                    @(2)               : NSArray.new };

NSObject *allKeys; 
// we make no assumptions about which type @allKeys will be,  but are going to assume
// we can NSLog it, so it needs to be a descendant of NSObject rather than 'id' so as 
// to definitely respond to the 'description' message — actually this is just compile
// time semantics, but if someone else reads this code it'll make it obvious to them 
// what we were thinking...

// some code to get all of the keys stored in the dictionary and print them out;
// should print an array containing the strings 'favouriteGarment', '@allKeys' and
// the number 2
allKeys = [someDictionary valueForKey:@"@allKeys"];
NSLog(@"%@", allKeys);

// some code to get the object named '@allKeys' from the dictionary; will print
// a description of the image created by loading photoOfKeys.jpg, above
allKeys = [someDictionary objectForKey:@"@allKeys"];
NSLog(@"%@", allKeys);
// `objectForKey is analogous to `objectForKeyedSubscript:`, aka
allKeys = someDictionary[@"@allKeys"];

allKeys является свойством NSDictionary, как описано здесь .Я также добавил отображение из всех ключей NSString на фотографию некоторых клавиш.Использую ли я методы кодирования ключ-значение valueForKey: или метод поиска NSDictionary objectForKey:, диктует, читать ли мне свойство экземпляра объекта или отправлять экземпляру объекта сообщение с просьбой выполнить свою уникальную работу.

17 голосов
/ 20 декабря 2010
  1. objectForKey: - это метод в NSDictionary для доступа к объекту, связанному с ключом.valueForKey: - это метод в NSObject для доступа к любому значению, связанному с любым объектом, через имя метода доступа, свойства и / или переменной экземпляра.
  2. valueForKeyPath: можно рассматривать как сокращениена несколько звонков valueForKey:.Вы можете думать об этом как о xpath, если хотите.

Эти два оператора приведут к одинаковому выводу:

// Using nested valueForKey:
NSLog(@"%@", [[myObject valueForKey:@"foo"] valueForKey:@"bar"]);
// Can be done with a single valueForKeyPath;
NSLog(@"%@", [myObject valueForKeyPath:@"foo.bar"]);

valueForKey: и valueForKeyPath:являются частью KVC (Key Value Coding).Введение и подробную документацию можно найти здесь: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueCoding/

1 голос
/ 20 декабря 2010
  1. valueForKey: и valueAtKeyPath: являются методами, определенными в неформальном протоколе NSKeyValueCoding, и реализации по умолчанию для обоих типов предоставляются корневым классом NSObject.

    objectForKey: - это метод NSDictionary.

  2. valueForKey: принимает ключ к свойству, а valueAtKeyPath: - так называемый путь к ключу. Ключевой путь - это разделенный точками путь к определенному свойству, например @"relationship.property".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...