Внутренний, 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
действительно делают.
Понятно, что '@selector (...)' является 'SEL' как' "..." 'для' const char * 'или' @ "..." 'является' NSString * '. –