2013-10-11 2 views
4
typedef struct objc_selector *SEL; 

В коде выше, SEL Тип в объективе-c является указателем на struct objc_selector. Так что, если я делаю SEL переменной как:Как работают SEL и @selector?

SEL aSel = @selector(instanceMethod) //Like this 

Что происходит? Что сделал @selector сделать методом экземпляра, instanceMethod?

+1

Понятно, что '@selector (...)' является 'SEL' как' "..." 'для' const char * 'или' @ "..." 'является' NSString * '. –

ответ

7

Директива @selector просто принимает имя метода и возвращает соответствующий идентификатор для этого метода. Этот идентификатор используется для определения, какой метод для вызова, когда селектор делает в конечном итоге получить выполняется:

SEL aSel = @selector(instanceMethod); 

// Calls -instanceMethod on someObject 
[someObject performSelector:aSel]; 

Вы можете найти детали в Apple's documentation.

+0

Еще одна вещь, если 'aSel' - это указатель на структуру, что именно находится в структуре? – MiguelC

+0

@MiguelC: см. Ответ hamstergene, который был только что опубликован. – BoltClock

18

Внутренний, SEL эквивалентен const char[], который просто хранит имя метода. На самом деле, они просто C строк:

(lldb) p _cmd 
(SEL) $0 = "windowDidLoad" 
(lldb) p (const char*) _cmd 
(const char *) $1 = 0x91ae954e "windowDidLoad" 

Важным исключением является то, что эти указатели являются глобально уникальными в этом процессе, даже через статические и динамические модули границ библиотеки, поэтому они сопоставимы с использованием ==. В отличие от строк C, которые нельзя сравнивать по значениям указателя ("instanceMethod" == @selector(instanceMethod) может и будет сбой), селектора сравнимы по значению указателя: независимо от того, как был создан селектор, два значения SEL для одного и того же селектора всегда равны.

@selector(instanceMethod) синтаксис создает строку C "instanceMethod", затем переходит к функции выполнения Obj-C, которая превращает ее в уникальное значение указателя, соответствующее этой строке. В основном это

SEL sel = @selector(instanceMethod); 
SEL sel = sel_registerName("instanceMethod"); 

P.S. struct objc_selector не существует, он должен сделать значения SEL несовместимыми с строками C и скрыть сведения о реализации селектора от вас. Для лучшего понимания вы можете прочитать в Obj-C runtime source code for selectors то, что эти sel_getName и sel_registerName действительно делают.

+2

Чтобы подчеркнуть эту последнюю точку; ** не рассматривайте SEL как совместимый с символом 'char *'. **. Это деталь реализации, которая * может измениться в будущем (вероятно, это не будет связано с соображениями совместимости ... но это может быть). – bbum

+2

Это отличная информация, вкратце сформулированная и не затронутая в ответах на другой вопрос, который, по-видимому, дублирует этот вопрос. Благодаря! –

Смежные вопросы