SEL和@selector如何工作?

Mig*_*elC 5 objective-c

typedef struct objc_selector  *SEL;
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,SEL键入objective-c是指向struct objc_selector.所以,如果我做一个SEL像这样的变量:

SEL aSel = @selector(instanceMethod) //Like this
Run Code Online (Sandbox Code Playgroud)

怎么了?@selector对实例方法做了什么,instanceMethod

ham*_*ene 22

在内部,SEL等同于const char[]简单地保存方法名称.实际上,它们只是C字符串:

(lldb) p _cmd
(SEL) $0 = "windowDidLoad"
(lldb) p (const char*) _cmd
(const char *) $1 = 0x91ae954e "windowDidLoad"
Run Code Online (Sandbox Code Playgroud)

重要的例外是这些指针在整个过程中是全局唯一的,甚至跨静态模块和动态库边界,因此它们具有可比性==.与指针值无法比较的C字符串("instanceMethod" == @selector(instanceMethod)可能失败)不同,选择器与指针值相当:无论如何创建选择器,SEL同一选择器的两个值总是相等.

@selector(instanceMethod)语法创建C字符串"instanceMethod"然后传递给Obj-C运行时函数,该函数将其转换为与该字符串对应的唯一指针值.它基本上是做什么的

SEL sel = @selector(instanceMethod);
SEL sel = sel_registerName("instanceMethod");
Run Code Online (Sandbox Code Playgroud)

PS struct objc_selector不存在,它是使SEL值与C字符串不兼容,并隐藏选择器实现细节.为了更好地理解,您可以在Obj-C运行时源代码中读取选择器的内容sel_getNamesel_registerName实际内容.

  • 强调最后一点;**不要将SEL视为与`char*`.**兼容.这是*可能*将来发生变化的实现细节(出于兼容性原因可能不会......但它可能会). (3认同)
  • 这是一个很好的信息,简明扼要,并没有在这个问题重复的另一个问题的答案中涵盖.谢谢! (3认同)

Bol*_*ock 9

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

SEL aSel = @selector(instanceMethod);

// Calls -instanceMethod on someObject
[someObject performSelector:aSel];
Run Code Online (Sandbox Code Playgroud)

您可以在Apple的文档中找到详细信息.