В чем разница между методом, селектором и сообщением в Objective-C?
Какая разница между методом и селектором?
Ответ 1
Это отличный вопрос.
-
Селектор. Селектор - это имя метода. Вы знакомы с этими селекторами:
alloc
,init
,release
,dictionaryWithObjectsAndKeys:
,setObject:forKey:
и т.д. Обратите внимание, что двоеточие является частью селектора; это то, как мы идентифицируем, что этот метод требует параметров. Также (хотя это очень редко), вы можете иметь такие селектора:doFoo:::
. Это метод, который принимает три параметра, и вы вызываете его как[someObject doFoo:arg1 :arg2 :arg3]
. Нет требования, чтобы перед каждой частью компонентов селектора были буквы. Как я уже сказал, это крайне редко, и вы не найдете его в рамках Cocoa. Вы можете работать с селекторами непосредственно в Cocoa. Они имеют типSEL
:SEL aSelector = @selector(doSomething:)
илиSEL aSelector = NSSelectorFromString(@"doSomething:");
-
Сообщение - сообщение является селектором и аргументами, которые вы отправляете вместе с ним. Если я скажу
[dictionary setObject:obj forKey:key]
, тогда "сообщение" является селекторомsetObject:forKey:
плюс аргументыobj
иkey
. Сообщения могут быть инкапсулированы в объектNSInvocation
для последующего вызова. Сообщения отправляются получателю. (т.е. объект, который "получает" сообщение). -
Метод - метод представляет собой комбинацию селектора и реализации (и сопутствующих метаданных). "Реализация" - это фактический блок кода; это указатель на функцию (a
IMP
). Фактический метод может быть извлечен изнутри с помощью структурыMethod
(извлекаемой из среды выполнения).
Некоторые другие связанные вещи, о которых вы не просили:
-
Подпись метода - подпись метода представляет типы данных, возвращаемые и принятые методом. Они могут быть представлены во время выполнения через
NSMethodSignature
и (в некоторых случаях) rawchar*
. -
Реализация - фактический исполняемый код метода. Его тип во время выполнения -
IMP
, и это действительно просто указатель на функцию. iOS 4.3 включает новую возможность превратить блок вIMP
. Это действительно здорово.
Одна из интересных вещей, которую нужно реализовать, - это то, что имя метода (селектор) отличается от реализации метода (IMP). Это означает, что вы можете поменять их, если вы чувствуете смелость. Вы также можете добавлять и удалять методы во время выполнения, потому что все, что вы делаете, редактирует запись в хеш-таблице: ключ является селектором, а значение - IMP
метода. Это позволяет вам делать действительно сумасшедшие и странные вещи. Это не для слабонервных.:)
Ответ 2
Метод - это реализация, которая выполняется, когда объект или класс просят выполнить какое-либо действие. Он входит в сферу его содержащего класса и поэтому отличается при ссылке через какой-либо другой класс. Селектор - это идентификатор, который представляет имя метода. Он не связан ни с каким конкретным классом или методом и может использоваться для описания метода любого класса, будь то метод класса или экземпляра.
Просто селектор похож на ключ в словаре. Он может рассказать вам, о каком методе кто-то говорит, но только если у вас также есть словарь (класс или объект). Метод - это то, что вы получаете, когда вы запрашиваете значение из словаря, используя селектор в качестве ключа.
Ответ 3
На этом сайте есть хороший обзор всей терминологии: http://www.otierney.net/objective-c.html
Посмотрите ссылку, но я дам краткое резюме:
Метод по существу подобен методу функции, к которому вы привыкли на своем любимом языке программирования.
Сообщение (из статьи) "Сообщение может быть динамически перенаправлено другому объекту. Вызов сообщения об объекте в Objective-C не означает, что объект реализует это сообщение, просто он знает, как реагировать на это как-то через непосредственное выполнение этого или пересылку сообщения объекту, который знает, как это сделать."
Селекторы могут означать две вещи. Он может ссылаться на имя метода или "ссылается на уникальный идентификатор, который заменяет имя при компиляции исходного кода. Скомпилированные селекторы имеют тип SEL". (от: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocSelectors.html)