SEL方法选择器

在Objective-C中,选择器(selector)有两个意思。 一是指在代码中的方法的名称。二是指在编译是用于替换方法名称的唯一的标识符。编译后的选择器的为SEL类型。所有名称相同的方法拥有同一个选择器。通过使用选择器可以调用对象的一个方法。这是Cocoa中目标-动作这一模式能得以实现的基础。

方法和选择器

出于效率的考虑,编译后的代码中并不是使用ASCII码表示的方法名称来作为方法的选择器的。编译器会把每一个方法的名称写入到一张表中;然后用唯一的一个标识符与之结对,这样来表示运行时的方法。运行时系统确保了这种标识符的唯一性:不会出现相同的两个选择器;所有名称相同的方法有用唯一同一个选择器。

SEL和@selector

编译的选择器拥有一种特殊的类型:SEL,以便和其它的数据类型进行区分。有效的选择器都是非0值的。对SEL类型的赋值必须由系统进行;其他的赋值方式都是无益的。
        指令@selector()表示使用编译的选择器,而不是完整的方法名称。如下,setWidth:height:的选择器被赋值给了setWidthHeight变量:
SEL setWidthHeight;
setWidthHiehgt = @selector(setWidth:height:);
         在编译时使用@selector指令来给SEL类型的变量赋值是效率最高的。然而,在某些情况下,可能需要将字符串转换成运行时的选择器。此时可以使用NSSelectorFromString函数来完成:
setWidthHeight = NSSelectorFromString(aBuffer);
        反向的转换也是可以的。函数NSStringFromSelector返回一个选择器对应的方法名称:

[cpp] view plain copy

  1. NSString * method;
  2. method = NSStringFromSelector(setWidthHeight);

 

方法和选择器

编译的选择器是以方法名称为区分的,而不是以方法的实现。一个类中的display方法的选择器和另外类中的display方法的选择器是同一个。这点对于多态性和动态绑定来说是非常重要的。这使得我们可以为不同类的对象发送相同的消息。如果不同的方法实现对应的是不同的选择器,那么消息和函数调用将没有什么区别。相同名称的类方法和实例方法对应的选择器也是同一个。然后由于两者的作用域是不同的,因此这不会造成冲突。一个类中是可以同时定义display类方法和display实例方法的。

方法的返回值及其参数的类型

        发送消息的例行程序只有通过选择器才能访问方法的实现。因此,它处理所有相同名称的方法的选择器的方式是一样的。它能够从选择器中判断方法的返回值及其参数的类型。因此,除了向静态类型的接收者发送消息之外,动态绑定要求所有名称相同的方法必须具有相同的返回值和参数类型。(静态类型的接收者是个例外,因为在编译时就可以从对应的类中感知到方法的具体实现。)

尽管名称完全一样的类方法和实例方法拥有相同的选择器,它们的参数和返回值的类型可以是不同的。

运行时发送可变消息

NSObject协议中定义的performSelector:,performSelector:WithObject:,performSelector:withObject:withObject:方法都是接收一个SEL类型的变量作为其第一个参数。这三个方法都是直接把消息映射为对应的函数。例如:[friend performSelector:@selector(gossipAbout:) withObject:aNeighbot];和下面的语句是等价的:[friend gossipAbout:aNeighbot];上面的三个方法使得我们可以再运行时发送不同的消息。这正如和运行时接收消息的对象是可变的一样。在发送消息的表达式中,接收者和消息都可以是变量:

[cpp] view plain copy

  1. id helper = getTheReceiver();
  2. SEL request = getTheSelector();
  3. [helper performSelector:request];

在上面的示例程序中,接收者(helper)是在运行时通过一个假定的函数getTheReceiver而动态选择的;要执行的方法(request)同样也是在运行时通过函数getTheSelector来动态决定的。

译者注:从上面的示例中可以看出,接收消息的对象和发送的具体消息在运行时都是可变的。所以可变消息指的就是上面的这种可变性,而不仅仅局限于发送的消息是可变的。

注意:

performSelector:及其他的方法的返回值类型都是id。如果执行方法的返回值类型不是id类型,则应该对其进行适当的转换。强制的类型转换并不是对所有类型都适用的。执行方法的返回值应该是指针或者是和指针相兼容的类型。

时间: 2024-08-06 10:18:06

SEL方法选择器的相关文章

IOS学习 - 方法选择器Selector的相关使用

问题的由来 Objective-C是一门动态的语言,只要有可能,Objective-C总会使用动态的方式来解决问题,比如它尽可能的将编译和连接要做的事推迟到运行时,所以它需要一个强大的运行时系统(runtime)来执行编译好的代码.runtime的角色类似于Objective-C语言的操作系统,是Objective-C的灵魂.Objective-C的很多特性都是基于这个强大的运行时的,是十分值得去学习理解的. 动态语言Objective-C很常见的一个消息发送语句(比较准确的说是消息发送,在不混

方法选择器

//选择器是变量类型 SEL sel = @selector(memoryClear); //选择器有点像函数指针,都能代表方法. //选择器变量sel存储的是能唯一代表方法名的标识(1001). //@selector(方法名),@selector能取得标识方法名的那个唯一的标识 SEL sel = @selector(memoryClear); //通过选择器可以直接调用私有方法.(不建议使用) [xiaoming performSelector:sel]; //通过performSelec

iOS runtime机制 和数据库结合 使用方便开发

1 首先说一下 runtime 运行机制 对于OC 这门高级编程语言 其实在语言底层的实现 是用C语言来实现的 一个OC的类 翻译成C 语言其实就是一个结构体的类型,当然结构体是非常复杂的包括了这个类的所有信息,类的继承还是有点难度的,暂时不用考虑类的继承的问题,只要知道OC类 底层是转换成 C语言的结构体! 我们先看一下 OC 是怎样发送消息的 也就是对应C语言是如何实现函数的调用的过程! [obj makeText];   //obj 这个类发送了一个  makeText的消息 之后runt

Objective-C总Runtime的那点事儿(一)消息机制

Objective-C总Runtime的那点事儿(一)消息机制 RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何二义性.OC的函数调用成为消息发送.属于动态调用过程.在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错.而C语言在编译阶段就会报错).只有在真正运行的时候才

Objective-C Runtime机制详解

Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时做的事放到了运行时来处理.同时OC也是一门简单的语言,很大一部分是C的内容,只是在语言层面上加了关键字和语法,真正让OC强大的是它的运行时,它很小却很强大,其中核心是消息分发.这种动态语言的优势在于:我们写代码时更加灵活,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现. 这种特性意味着OC不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于OC来说,这个运行时系统就像一个操作系统一样.这个运行时系

iOS开发笔记--Runtime那点事

Objective-C总Runtime的那点事儿(一)消息机制 最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎必问,例 如:RunLoop,Block,内存管理等.其他的问题如果有机会我会在其他文章中介绍.本篇文章主要介绍RunTime. RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编

Objective-C总Runtime的那点事儿(一)消息机制【转】

RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何二义性.OC的函数调用成为消息发送.属于动态调用过程.在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错.而C语言在编译阶段就会报错).只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用. 那OC是怎么实现动态调

oc - runtime运行机制

Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时做的事放到了运行时来处理.同时OC也是一门简单的语言,很大一部分是C的内容,只是在语言层面上加了关键字和语法,真正让OC强大的是它的运行时,它很小却很强大,其中核心是消息分发.这种动态语言的优势在于:我们写代码时更加灵活,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现. 这种特性意味着OC不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于OC来说,这个运行时系统就像一个操作系统一样.这个运行时系

一.oc基础

 如何构建一个oc客户端程序 1. oc 第一个程序 2. oc 的数据类型 3. oc 的书写规范 4. oc 的格式符 1.如何构建一个oc客户端程序? 开Xcode,选择Create a new Xcode project 点击左边的OS X ->Command Line Tool 控制行工具 ProductName:项目名称 OrganizationName:组织名称 Organization Identifier: 组织标示 (一般将公司域名倒过来写) Language:使用的开发语言