Какое свойство Objective-C разрешается во время выполнения?

Какое свойство Objective-C разрешается во время выполнения? Будет ли вызов [obj valueForKey:@"property"] всегда давать один и тот же результат?

e.g.

obj.property


person Boon    schedule 22.10.2013    source источник
comment
Я почти уверен, что где-то в документации Apple описано, как valueForKey работает на разных платформах.   -  person Bryan Chen    schedule 23.10.2013
comment
Может ли кто-нибудь противостоять отрицательному голосованию, это законный вопрос о кодировании!   -  person Boon    schedule 23.10.2013


Ответы (2)


Во-первых, обратите внимание, что 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 обрабатывается специально, как мне кажется).

person Rob Napier    schedule 23.10.2013
comment
А как насчет obj.property = value? Это эквивалентно [obj setProperty:value]? - person Boon; 23.10.2013
comment
Да. установщики точечной нотации преобразуются в соответствующий метод набора. - person Rob Napier; 23.10.2013
comment
obj.property не совсем то же самое, что и [obj property]. Если у геттера другое имя, запись через точку эквивалентна отправке сообщения, соответствующего имени геттера, а не имени свойства. - person cHao; 23.10.2013
comment
@cHao, хорошая мысль. Преобразование из точечной нотации в геттер, а имя по умолчанию для геттера — это имя свойства. Аналогично для сеттера. - person Rob Napier; 23.10.2013

obj.property — это то же самое, что [obj property], а не [obj valueForKey:@"property"];. Последнее является частью системы под названием Key Value Coding, которая отделена от свойств.

person Catfish_Man    schedule 22.10.2013
comment
Он разрешается в objc_msgSend, как и все вызовы методов. Доступ к свойствам — это просто вызовы методов. - person Catfish_Man; 23.10.2013
comment
class_getProperty занимается самоанализом. это не используется для вызова чего-либо - person Daij-Djan; 23.10.2013