@selector和SEL
遇到selector发现不是很明白,网上搜到的零零星星的介绍也不成体系,索性自己翻译一下,加深一下印象。原文来自官方API文档下的Selectors。
Selectors
在OC中,selector有两层含义。
1、当selector在源代码中被用来指向一个对象的时候,selector可以仅仅指这个方法的名称。
2、代码编译的时候会生成一个唯一的标示符,selector也可以指向该标示符。
selectors的编译类型为SEL。所有有同样名称的方法都有同样的selector。针对某个对象(object),你可以使用selector去调用它的方法。这给Cocoa的目标-行为设计模式(the target-action design pattern,注:关于这部分在该篇API的最后进行了说明)提供了执行的基础。
Methods and Selectors
为了提高效率,在编译规则(compiled code)中一个完整的ASCII名称不被作为方法的selectors。取而代之的方法是,编译器将每一个方法的名称写到一个table中,然后跟一个唯一的标示符配对,该标示符在运行过程中会代表一个具体的方法。运行系统(runtime system)确保每一个标示符都是唯一的:没有两个selector是相同的,而且所有有同样名称的方法有同样的selector
SEL and @selector
selector编译后被指定到一种特殊的类型——SEL来与其它类型进行区分。有效的selector永远不会为0.你必须让系统给方法分配SEL标示符,自行任意分配的标示符是无效的。
你应该使用@selector()指令将方法名传递给编译的selector,而不是直接使用一个方法的全名。比如,下面的方法可以获得setWidth:height: 方法的selector,并且分配给setWidthHeight变量:
SEL setWidthHeight;
setWidthHeight = @selector(setWidth:height:);
最有效的的方式是在编译的时候调用@selector()指令给SEL变量赋值。但在有些情况下,你可能需要在运行时候将字符串转换给某个selector。你可以使用NSSelectorFromStringn函数完成这项工作:
setWidthHeight = NSSelectorFromString(aBuffer);
反着转换也是可行的。NSStringFromSelector函数可以返回某个selector的方法的名称:
NSString *method;
method = NSStringFromSelector(setWidthHeight);
Methods and Selectors
selector编译后可以识别方法名称,但不实现方法(not method implementations)。比如,对于一个类而言,它的display方法和其它同样定义了display方法的类有相同的selector。对于动态绑定和多态性而言这是必不可少的,它可以让你给不同类的接收器发送相同的方法。如果每一个执行方法都有一个selector,那么发送这条信息就跟调用了一个函数回调(function call)没什么区别了。
具有相同名称的类方法和实例方法被分配了相同的selector,单因为他们属于不同的领域,这两者之间也不会产生混淆。一个类能定义display方法,附加给一个实例方法。
Method Return and Parameter Types
通告程序(messaging routine)只能通过selector访问方法实体(method implementation),所以它用同样的selector处理所有方法 (注:这句话不理解,附原文so it treats all methods with the same selector alike)。通告程序(it)可以通过selector辨别一个方法的返回类型、以及参数的数据类型。因此,除非通告(message)是发送给静态类型的接收器,否则对于动态绑定接收器,会要求所有有同样名称方法的实例页有同样的返回类型和参数类型。(对于该规则,静态类型的接收器属于例外的原因是编译器能从类的类型了解该方法实体。)
虽然相同名称的类方法和实例方法是使用同样的selector代表的,它们可以有不同的参数类型和返回值类型。
Varying the Message at Runtime
NSObject协议中定义的 performSelector:, performSelector:withObject:,和 performSelector:withObject:withObject:方法使用SEL标示符作为它们的初始化参数。所有这三个方法(注:我很奇怪为什么是三个,但是原文就是写的三个...)直接映射到通告功能(massaging function)。例如:
[friend performSelector: @selector(gossipAbout:)
withObject: aNeighbor];
相当于
[friend gossipAbout:aNeighbor];
这些方法使应用运行时改变message成为可能,就像可以改变一个接收message的object一样。Variable names can be used in both halves of a message expression:
id helper = getTheReceiver();
SEL request = getTheSelector();
[helper performSelector:request];
在这个例子中,接收器helper在运行时候进行选择(通过一个假设的getTheReceiver函数),方法接收器页要求在运行时执行request(同样通过一个假设的getTheSelector函数)
Note:performSelector: 方法和它其它同伴的方法都返回一个类型为id的对象,如果当前执行的方法返回一个不同的类型,它应当被转换为适当的类型。(但,转换不适用于所有类型,方法应当返回一个指针或者一个指针兼容的类型)
@selector和SEL的更多相关文章
- Method Swizzle黑魔法,修改 ios 系统类库方法 SEL IMP
Method Swizzle黑魔法,修改 ios 系统类库方法 版权声明:本文为博主原创文章,未经博主允许不得转载. 一般来说,系统提供的方法已经足够开发了,但是有的时候有些需求用普通方法不好做. ...
- 读Zepto源码之Selector模块
Selector 模块是对 Zepto 选择器的扩展,使得 Zepto 选择器也可以支持部分 CSS3 选择器和 eq 等 Zepto 定义的选择器. 在阅读本篇文章之前,最好先阅读<读Zept ...
- OC的特有语法-分类Category、 类的本质、description方法、SEL、NSLog输出增强、点语法、变量作用域、@property @synthesize关键字、Id、OC语言构造方法
一. 分类-Category 1. 基本用途:Category 分类是OC特有的语言,依赖于类. ➢ 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式 ● 继承 ● 分类(Categor ...
- SEL是啥玩意
一.了解SEL前的准备-----isa指针简述 1.一个类就像一个 C 结构,NSObject 声明了一个成员变量: isa.由于 NSObject 是所有类的根类,所以所有的对象都会有一个 isa ...
- Objective-C runtime初识
Objective-C Runtime Describes the macOS Objective-C runtime library support functions and data struc ...
- iOS----应用的旋转---Orientations
此博文主要针对IOS应用, 是屏幕旋转相关问题的一个总结. 主要内容有: IOS5,6,7不同版的适配. 强制旋转和自动旋转. QQ : 1101819159 邮箱: GeekiVan@aliyun. ...
- 4.1/4.2 多线程进阶篇<上>(Pthread & NSThread)
本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书” 本文源码 Demo 详见 Githubhttps://github.com/shorfng ...
- runtime 第四部分method swizzling
接上一篇 http://www.cnblogs.com/ddavidXu/p/5924597.html 转载来源http://www.jianshu.com/p/6b905584f536 http:/ ...
- Scrapy爬取自己的博客内容
python中常用的写爬虫的库有urllib2.requests,对于大多数比较简单的场景或者以学习为目的,可以用这两个库实现.这里有一篇我之前写过的用urllib2+BeautifulSoup做的一 ...
随机推荐
- 对于进程没杀死占用内存和cpu行为的方法
在跑机器学习或者深度学习的过程中有可能遇到没杀死进程的情况,但是程序的入口又没关掉,尤其是我使用jupyter从远程Linux映射到windows浏览器跑程序的时候 对于上面的问题, 首先运行 hto ...
- 关于 vee-validate直接引用的方法
转载于:https://blog.csdn.net/hy111/article/details/79046500?%3E 由于当前项目使用的是基于jQuery的前端结构,尝试在新增需求中使用VUE2, ...
- python与MySQL数据库
python与MySQL数据库 慕课网连接 我使用的软件:python2.7 + MySQL+ Navicat for MySQL + Atom 注意:你的数据库表格类型的引擎为:InnoDB :字符 ...
- C#读取xml文件写入到TreeView中
开发过程中我们会遇到一些读取xml文件的时候,下面是我学习的整理. 用XmlDocument读取加载 XmlDocument doc = new XmlDocument(); doc.Load(&qu ...
- 201621123034 《Java程序设计》第12周学习总结
作业12-流与文件 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系统或购物车 使用流与文件改造你的图书馆管理系统或购物车 ...
- 详解Linux运维工程师应具备的十大技能
Linux系统如果是学习可以选用Redhat或CentOS,特别是CentOS在企业中用得最多,当然还会有其它版本的,但学习者还是以这2个版本学习就行,因为这两个版本都是兄弟,没区别的,有空可以再研究 ...
- 朗格拉日计数(counter)
朗格拉日计数(counter) 题目描述 在平面上以圆周等分排列着n个带标号(标号为1-n)的点,你需要计算有多少个三元组(a,b,c),满足a<b<c而且标号为a,b,c的点在圆上分布的 ...
- java.security.InvalidKeyException: IOException : Short read of DER length
今天支付服务器测试退款的时候爆了异常:Caused by: java.security.InvalidKeyException: IOException : Short read of DER len ...
- linux常用60条命令 转
Linux必学的60个命令 Linux提供了大量的命令,利用它可以有效地完成大量的工作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命 ...
- YYH的营救计划(NOIP模拟赛Round 6)
题目描述 “咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!YYH感动的热泪盈眶,开起了门…… YYH的父亲下班回家,街坊邻居说YYH被一群陌生人强行押上了警车!YYH的父 ...