这篇文章只介绍SEL,会包括SEL的官方定义、官方描述、创建selector的源码分析。
既然文章标题是讨论SEL,那么就不会添加进来那些烂大街的内容,什么“消息发送”、“Method结构体”、“runtime...”,这些个有的没的都是耍流氓。
很久以来都有这么个面试题: 请解释SEL是什么
一开始呢,我说不清楚SEL是什么,就知道SEL是selector的类型,而selector是方法名。那这个selector和SEL是对象?是字符串?是结构体?是指针?到底是啥就叫不准了。
所以我上网去搜了一下。不管是度娘还是谷歌找到的博客,都没有很满意的答案。所以干脆找时间,自己去官方文档和源码中找答案。
进入正题
从头来看SEL和selector,先从苹果介绍SEL的官方文档开始,文档地址。
SEL
定义
我们都知道 SEL 是selector的类型,从文档中看,SEL的定义是:
typedef struct objc_selector *SEL;
也就是说 SEL 是一个指针类型,SEL 修饰的指针指向 objc_selector 结构体。到这,得出一个暂时性结论:
我们平时创建和获取的 selector 都是一个指向objc_selector 结构体的指针。
虽然我没有在文档和源码中找到这个 objc_selector 结构体的内部实现,按照文档中的意思这是一个非透明的类型,但是到这里可以否定很多文章中的说法,selector 是指针,一个指向 objc_selector 结构体的指针,绝不是什么函数指针,在这里就不讨论IMP了。
描述
为什么在查资料的时候有很多文章会说 selector 是字符串呢?再看官方文档Discussion 部分的几个重点:
方法的 selector 是一个已被Objective-C运行时注册过或映射过的C语言字符串
如果想使用 selector ,必须使用 sel_registername 的返回值或者编译器指令@selector()
这里有一个根本性区别就是,文档中特意提到了这个字符串是被映射过或者注册过(实际上是注册到NXMapTable中做了相应的映射关系,后面会说)。
我们平时使用selector的时候,一般都可以直接把SEL当做字符串打印,比如:
SEL xxoo_selector = @selector(init);
NSLog(@"%s", xxoo_selector);
控制台:
2019-04-19 11:05:43.404155+0800 SEL_Test[1352:42639] init
我们知道,结构体指针指向的地址其实就是第一个成员的地址,这与数组指针指向的地址和首元素地址相同是一样的道理。因此&#