Какое свойство Objective-C разрешается во время выполнения? Будет ли вызов [obj valueForKey:@"property"] всегда давать один и тот же результат?
e.g.
obj.property
Какое свойство Objective-C разрешается во время выполнения? Будет ли вызов [obj valueForKey:@"property"] всегда давать один и тот же результат?
e.g.
obj.property
Во-первых, обратите внимание, что obj.property
точно такое же, как [obj property]
. Точечный синтаксис — это просто синтаксический сахар. Хотя есть некоторые небольшие детали реализации во время выполнения, связанные со свойствами, которые отличаются от других методов, для целей этого обсуждения думайте только в терминах «у меня есть ivar с именем _key
и метод с именем -key
». Тот факт, что вы создали этот ivar и метод, объявив свойство, не имеет значения для valueForKey:
.
valueForKey:
— это метод, и он может быть переопределен классом, чтобы возвращать все, что ему нравится. Поведение по умолчанию заключается в том, что valueForKey:
сначала ищет метод, имя которого соответствует ключу, и возвращает результат. В подавляющем большинстве случаев это означает, что если у вас есть свойство, то valueForKey:@"property"
вернет его значение.
Полный путь поиска для реализации valueForKey:
по умолчанию объясняется в "Подробности реализации поиска доступа", но вот "короткая" версия:
get<Key>
, <key>
, is<Key>
(да, в первую очередь это выглядит как getKey
, что немного смущает, потому что вы не должны ставить геттеры с префиксом get
, если только они не возвращают значения по ссылке, но вот и все; это проверяется в первую очередь.)
countOf<Key>
, objectIn<Key>AtIndex:
и <key>AtIndexes
. Если найдена их правильная комбинация, то возвращается прокси-объект, подобный NSArray.
countOf<Key>
, enumeratorOf<Key>
и memberOf<Key>:
. Если все три найдены, возвращается прокси-объект, подобный NSSet.
Если accessInstanceVariablesDirectly
равно YES
(по умолчанию), то проверяются ивары с именами _<key>
, _is<Key>
, <key>
или is<Key>
. Да, это способ доступа к приватным параметрам объекта.
Если все остальное не удалось, то он вызывает valueForUndefinedKey:
, который может бесплатно возвращать результат (и это на самом деле очень полезно, если вы хотите общее хранилище ключей/значений).
Но в девяти случаях из десяти вы получите значение метода с именем <key>
.
Примечание: valueForKey:
возвращает объект. Если возврат является числовым скаляром (включая BOOL
), он вернет NSNumber
. В противном случае он вернет NSValue
. Существует особая обработка для NSPoint
, NSRange
, NSRect
и NSSize
(на Mac; на iOS только NSRange
обрабатывается специально, как мне кажется).
obj.property
не совсем то же самое, что и [obj property]
. Если у геттера другое имя, запись через точку эквивалентна отправке сообщения, соответствующего имени геттера, а не имени свойства.
- person cHao; 23.10.2013
obj.property — это то же самое, что [obj property], а не [obj valueForKey:@"property"];. Последнее является частью системы под названием Key Value Coding, которая отделена от свойств.
valueForKey
работает на разных платформах. - person Bryan Chen   schedule 23.10.2013