SEL是啥玩意
一、了解SEL前的准备-----isa指针简述
1、一个类就像一个 C 结构,NSObject 声明了一个成员变量: isa。由于 NSObject 是所有类的根类,所以所有的对象都会有一个 isa 的成员变量,而该 isa 变量指向该对象的类(空间)。
2、类在Objective-C中也是一个实体, 由于存在Objective-C 运行环境所有的类将有自己的存储空间。Objective-C 运行环境将为每个类分配空间。这里所说的 isa,正是指向这样一个类的空间, 从而建立类和对象之间的对应关系。
3、类空间(Class)包含了该类定义的成员变量,以及方法实现,,还包含了指向自己父类空间的指针。
4、Class里也有个isa的指针, 指向meteClass(元类)。元类保存了类方法的列表。当类方法被调用时,先会从本身查找类方法的实现,如果没有,元类会向他父类查找该方法。同时注意的是:元类(meteClass)也是类,它也是对象。元类也有isa指针,它的isa指针最终指向的是一个根元类(root meteClass)。根元类的isa指针指向本身,这样形成了一个封闭的内循环。
二、SEL 和 @selector()
1、selector 、 SEL 、@selector
(1)类中的方法以 selector 作为索引。selector 的数据类型是 SEL。
(2)虽然 SEL 定义成 char*(字符串),我们可以把它理解成 int。每个方法的名字对应一个唯一的 int 值。比如, 方法 addObject: 可能对应的是 12,当寻找该方法时,使用的是 selector,而不是名字 @"addObject:"
(3)Objective-C 数据结构中,存在一个 name - selector 的映射表如图 3.16

(4)SEL这个类型本质是类方法的编号(函数地址、函数指针、字符串、int、函数编号)
(5)可以理解 @selector() 就是取类方法的编号, 他的行为基本可以等同C语言的中函数指针, 只不过C语言中,可以把函数名直接赋给一个函数指针,而Object-C的类不能直接应用函数指针,这样只能做一个@selector语法来取。@selector的结果是SEL类型,所以说白了,@selector还是获得方法的编号(地址)。
小白总结:SEL其实是对方法的一种包装 , 将方法包装成一个SEL类型的数据(selector),去寻找对应的方法地址, 找到方法地址后就可以调用方法,这些都是运行时特性,发消息就是发送selector,然后根据selector找到地址,调用方法。 如果子类中找不到,就向上找,直到找到NSobject,没有就报错。SEL本身就是运行时特性的一个现实运用!

2、方法调用的过程及本质
(1)通俗理解 —— 对象调用方法时的寻找过程(寻找方法的过程): selector选择器机制
<1>首先把test这个方法名包装成SEL类型的数据(一个selector)
<2>根据SEL数据找到对应的方法地址
<3>根据方法地址调用响应的方法
<4>注意: 在这个操作过程中有缓存,第一次找的时候是一个一个的找(应该是找到了代码区中,一条条找),消耗性能之后再用到的时候直接使用 (个人理解:应该是放到“类对象”的方法列表中了,这也就不用重复检索了)。
(2)大神理解 ——objec_msgSend()函数
<1> 在编译的时候, 只要有方法的调用, 编译器都会通过 selector 来查找,所以(假设addObject的selector为12),调用方法:[myObject addObject:yourObject];
<2>上面将会编译变成:
objc_msgSend(myObject, 12, yourObject);
这里,objec_msgSend()函数将会使用 myObjec 的 isa 指针来找到 myObject 的类空间结构并在类空间结构中查找 selector 12 所对应的方法.如果没有找到,那么将使用指向父类的指 针找到父类空间结构进行 selector 12 的查找. 如果仍然没有找到,就继续往父类的父类一 直找,直到找到为止, 如果到了根类 NSObject 中仍然找不到,将会抛出异常。
<3>通过上面,我们可以看到, 这是一个很动态的查找过程。类的结构可以在运行的时候改变,这样可以很 容易来进行功能扩展,Objective-C 语言是动态语言, 支持动态绑定。
3、SEL的应用举例:
调用方法(本身就是把方法包装的),也可以定义SEL类型的变量,然后把这个变量作为参数

SEL是啥玩意的更多相关文章
- 神马玩意,EntityFramework Core 1.1又更新了?走,赶紧去围观
前言 哦,不搞SQL了么,当然会继续,周末会继续更新,估计写完还得几十篇,但是我会坚持把SQL更新完毕,绝不会烂尾,后续很长一段时间没更新的话,不要想我,那说明我是学习新的技能去了,那就是学习英语,本 ...
- Objective-C数据类型之id,SEL,BOOL,nil,NULL和NSNull
id id是指向Objective-C对象的指针,等价于C语言中的void*,可以映射任何对象指针指向他,或者映射它指向其他的对象.常见的id类型就是类的delegate属性. SEL SEL类型是 ...
- iOS开发 关于SEL的简单总结
SEL就是对方法的一种包装.包装的SEL类型数据它对应相应的方法地址,找到方法地址就可以调用方法.在内存中每个类的方法都存储在类对象中,每个方法都有一个与之对应的SEL类型的数据,根据一个SEL数据就 ...
- OC语言description方法和sel
OC语言description方法和sel 一.description方法 Description方法包括类方法和对象方法.(NSObject类所包含) (一)基本知识 -description(对象 ...
- SEL方法选择器
在Objective-C中,选择器(selector)有两个意思. 一是指在代码中的方法的名称.二是指在编译是用于替换方法名称的唯一的标识符.编译后的选择器的为SEL类型.所有名称相同的方法拥有同一个 ...
- SEL数据类型
// // main.m // 06-SEL数据类型 // // Created by apple on 14-3-18. // Copyright (c) 2014年 apple. All ...
- extjs DateField 的值用getValue()方法获取后是一大堆字符串,类似Tue Dec 07 2010 00:00:00 GMT 0800,这玩意存入数据库实在不好办。。。
extjs DateField 的值用getValue()方法获取后是一大堆字符串,类似Tue Dec 07 2010 00:00:00 GMT 0800,这玩意存入数据库实在不好办...所以要把它格 ...
- Objective C SEl 和@selector是怎么工作的||How do SEL and @selector work in iphone sdk?
SEL is a type that represents a selector in Objective-C. The @selector() keyword returns a SEL that ...
- 李洪强iOS开发之OC语言description方法和sel
OC语言description方法和sel 一.description方法 Description方法包括类方法和对象方法.(NSObject类所包含) (一)基本知识 -description(对象 ...
随机推荐
- (C/C++学习)14.C语言字符串处理函数(二)
说明:上节着重解释了字符串处理的库函数处理,这节将针对一些常用的需求,进行非库函数的处理. 一.去除某一个字符串中的某个字符 1.去除字符串右边的空格 void trimStrRightSpace(c ...
- 集合:Iterator
why ? when ? how ? what ? 为什么需要集合呢? 在数据结构中链表.树.堆等一些操作都是由我们自己写的,这些操作是不是可以提取出来,以后要用就直接拿来用就好,这样非常方便. Ja ...
- Java生成PDF文件(转)
原文地址:https://www.cnblogs.com/shuilangyizu/p/5760928.html 一.前言 前几天,做ASN条码收货模块,需要实现打印下载收货报表,经一番查找,选定iT ...
- this与const
在普通非const成员函数中,this是const指针,而在const成员函数中,this是const对象的const指针. class Foo { Foo& get_self1(void) ...
- 洛谷 3979 BZOJ 3083 遥远的国度
[题解] 这道题除去根操作就是普通的树链剖分了.但是有换根操作怎么处理呢? 我们可以发现如果现在的根不在查询的点的子树里,那么对本次查询没有影响.如果现在的跟在查询的点x的子树里,那么答案将变为整棵树 ...
- [bzoj1833][ZJOI2010][count] (数位dp)
Description 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. Input 输入文件中仅包含一行两个整数a.b,含义如上所述. Output 输出文 ...
- Oracle学习总结(4)——MySql、SqlServer、Oracle数据库行转列大全
MySql行转列 以id分组,把name字段的值打印在一行,逗号分隔(默认) select CustomerDrugCode,group_concat(AuditItemName) from noau ...
- Ubuntu16.04再次装机记
个人的吐槽 整个国庆假期(9天),基本上都在搭建PHP环境中耗费了. 是这样的——来大学报到前,想着大学里用个Dev-C++应该够了,于是把Ubuntu删了,腾出了100G的空间.到了CSU,加了团委 ...
- hdu 2604 矩阵快速幂模板题
/* 矩阵快速幂: 第n个人如果是m,有f(n-1)种合法结果 第n个人如果是f,对于第n-1和n-2个人有四种ff,fm,mf,mm其中合法的只有fm和mm 对于ffm第n-3个人只能是m那么有f( ...
- docker重新打包MySQL5.7镜像
1:先下载MySQL镜像 # docker pull mysql:5.7 2:运行镜像生成容器 # docker run --name mysql -p 3306:3306 -e MYSQL\_ ...