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 的文档中找到详细信息。