SEL和@selector如何工作?

时间:2013-10-11 15:49:30

标签: objective-c

typedef struct objc_selector  *SEL;

在上面的代码中,objective-c中的SEL类型是指向struct objc_selector的指针。所以,如果我创建一个SEL变量,如:

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

会发生什么? @selector对实例方法做了什么,instanceMethod

2 个答案:

答案 0 :(得分:19)

在内部,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_getNamesel_registerName实际执行的内容。

答案 1 :(得分:8)

@selector指令只接受方法名称并返回该方法的适当标识符。此标识符用于确定最终执行选择器时要调用的方法:

SEL aSel = @selector(instanceMethod);

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

您可以在Apple's documentation中找到详细信息。