Internally, SEL
is equivalent to const char[]
that simply holds method name. In fact, they are just C strings:
(lldb) p _cmd
(SEL) $0 = "windowDidLoad"
(lldb) p (const char*) _cmd
(const char *) $1 = 0x91ae954e "windowDidLoad"
The important exception is that these pointers are globally unique in the process, even across static modules and dynamic library boundaries, so they are comparable using ==
. Unlike C strings which can not be compared by pointer values ("instanceMethod" == @selector(instanceMethod)
may and will fail), selectors are comparable by pointer value: no matter how selector was created, two SEL
values for the same selector are always equal.
@selector(instanceMethod)
syntax creates C string "instanceMethod"
then passes to Obj-C runtime function which turns it into unique pointer value corresponding to that string. What it basically does is
SEL sel = @selector(instanceMethod);
SEL sel = sel_registerName("instanceMethod");
P.S. struct objc_selector
does not exist, it is to make SEL
values incompatible with C strings, and hide selector implementation details from you. For even better understanding, you may read in Obj-C runtime source code for selectors what those sel_getName
and sel_registerName
actually do.