Подтвердить что ты не робот

В чем разница между valueforKey:, objectForKey:, и valueForKeyPath:?

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

  • В чем разница между valueForKey: и objectForKey:? Разве это для NSDictionary (objectForKey:), а для других - valueForKey:, или это наоборот?

  • В чем разница между valueForKey: и valueForKeyPath:? Имеет ли он что-то общее с Core Data?

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

Дополнения:

Пример, закодированный по типу я и предполагающий, что 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 allKeys на фотографию некоторых клавиш. Я использую методы кодирования ключевого значения valueForKey: или метод поиска NSDictionary objectForKey:, определяет, читаю ли я свойство экземпляра объекта или отправляю ли экземпляр объекта сообщение с просьбой выполнить его уникальное задание.

Ответ 2

  • objectForKey: - это метод на NSDictionary для доступа к объекту, связанному с ключом. valueForKey: - это метод на NSObject для доступа к любому значению, связанному с любым объектом, через имя метода доступа, свойства и/или переменной экземпляра.
  • 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/

Ответ 3

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

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

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