关于SEL的一些总结

1.SEL的概述

SEL就是对方法的一种包装,是表示一个方法的selector的指针。包装的SEL类型数据它对应相应的方法地址,找到方法地址就可以调用方法,其定义如下:


objc_selector结构体的详细定义没有在头文件中找到。方法的selector用于表示运行时方法的名字。Objective-C在编译时,会依据每一个方法的名字、参数序列,生成一个唯一的整型标识(Int类型的地址),这个标识就是SEL。不用的类里面的相同名字相同声明的方法的身份证明是一样的。这样在程序执行的时候,runtime就不用费力的进行方法的名字比较来确定是执行哪一个方法了,只是通过一个整数的寻找就可以马上定位到相应的方法,然后找到相应的方法的入口地址,这样方法就可以被执行了。


示例代码:

ViewController.m

#import "ViewController.h"
#import "Selector.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    Selector * select =[[Selector alloc]init];
    [select performSelector:@selector(viewDidLoad) withObject:nil];
    SEL sel1 =@selector(viewDidLoad);
    NSLog(@"sel1:%p",sel1);
    NSLog(@"viewDidLoad:%p",_cmd);//_cmd本身代表所在方法的SEL
}
@end

 
Selector.m 

#import "Selector.h"
@implementation Selector
- (void)viewDidLoad {
    NSLog(@"Selector:%p",_cmd);
}
@end

上面的输出为:

2016-04-27 11:37:53.883 SEL  @selector()[6278:61711] Selector:0x106f674d5

2016-04-27 11:37:53.884 SEL  @selector()[6278:61711] sel1:0x106f674d5

2016-04-27 11:37:53.884 SEL  @selector()[6278:61711] viewDidLoad:0x106f674d5

注意点:

两个类之间,不管它们是父类与子类的关系,还是之间没有这种关系,只要方法名相同,那么方法的SEL就是一样的。每一个方法都对应着一个SEL。所以在 Objective-C同一个类(及类的继承体系)中,不能存在2个同名的方法,即使参数类型不同也不行。相同的方法只能对应一个SEL。这也就导致 Objective-C在处理相同方法名且参数个数相同但类型不同的方法方面的能力很差。如在某个类中定义以下两个方法:

- (void)setWidth:(int)width;
- (void)setWidth:(double)width;
当然,不同的类可以拥有相同的selector,这个没有问题。不同类的实例对象执行相同的selector时,会在各自的方法列表中去根据selector去寻找自己对应的IMP。
2.SEL的理解
工程中的所有的SEL组成一个Set集合,Set的特点就是唯一,因此SEL是唯一的。因此,如果我们想到这个方法集合中查找某个方法时,只需要去找到这个方法对应的SEL就行了,SEL实际上就是根据方法名hash化了的一个字符串,而对于字符串的比较仅仅需要比较他们的地址就可以了,可以说速度 上无语伦比!!但是,有一个问题,就是数量增多会增大hash冲突而导致的性能下降(或是没有冲突,因为也可能用的是perfect hash)。但是不管使用什么样的方法加速,如果能够将总量减少(多个方法可能对应同一个SEL),那将是最犀利的方法。那么,我们就不难理解,为什么 SEL仅仅是函数名了。

本质上,SEL只是一个指向方法的指针(准确的说,只是一个根据方法名hash化了的KEY值,能唯一代表一个方法),它的存在只是为了加快方法的查询速度。这个查找过程我们将在下面讨论。


我们可以在运行时添加新的selector,也可以在运行时获取已存在的selector,

我们可以通过下面三种方法来获取SEL:

1. sel_registerName函数
2. Objective-C编译器提供的@selector()

3. NSSelectorFromString()方法

SEL的用法主要有一下几种

1.SEL 变量名 = @selector(方法名字); //注意有参数时要带上:
2.SEL 变量名 = NSSelectorFromString(方法名字的字符串);
3.NSString *变量名 = NSStringFromSelector(SEL参数);

参考:

  1.http://www.cnblogs.com/yaski/archive/2009/04/05/1429735.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值