typedef struct objc_selector *SEL;
在上面的代码SEL
中,objective-c 中的 type 是一个指向struct objc_selector
. 因此,如果我创建一个SEL
变量,例如:
SEL aSel = @selector(instanceMethod) //Like this
怎么了?@selector
对实例方法做了什么instanceMethod
?
typedef struct objc_selector *SEL;
在上面的代码SEL
中,objective-c 中的 type 是一个指向struct objc_selector
. 因此,如果我创建一个SEL
变量,例如:
SEL aSel = @selector(instanceMethod) //Like this
怎么了?@selector
对实例方法做了什么instanceMethod
?
在内部,SEL
相当于const char[]
简单地保存了方法名。实际上,它们只是 C 字符串:
(lldb) p _cmd
(SEL) $0 = "windowDidLoad"
(lldb) p (const char*) _cmd
(const char *) $1 = 0x91ae954e "windowDidLoad"
重要的例外是这些指针在进程中是全局唯一的,甚至跨越静态模块和动态库边界,因此它们可以使用==
. 与不能通过指针值比较("instanceMethod" == @selector(instanceMethod)
可能失败和将失败)的 C 字符串不同,选择器可以通过指针值进行比较:无论选择器是如何创建的,SEL
同一个选择器的两个值总是相等的。
@selector(instanceMethod)
语法创建 C 字符串"instanceMethod"
,然后传递给 Obj-C 运行时函数,该函数将其转换为与该字符串对应的唯一指针值。它的基本作用是
SEL sel = @selector(instanceMethod);
SEL sel = sel_registerName("instanceMethod");
PSstruct objc_selector
不存在,它是让SEL
值与 C 字符串不兼容,并对你隐藏选择器实现细节。为了更好地理解,您可以在Obj-C 运行时源代码中阅读选择器的那些sel_getName
和sel_registerName
实际作用。
该@selector
指令仅采用方法名称并返回该方法的适当标识符。此标识符用于确定最终执行选择器时调用哪个方法:
SEL aSel = @selector(instanceMethod);
// Calls -instanceMethod on someObject
[someObject performSelector:aSel];
您可以在Apple 的文档中找到详细信息。