Selector

 在接触iOS的时候入门Demo都会接触到的一个方法:

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;

相应地,肯定会用到这样一处代码:

    [self.speakButton addTarget:self action:@selector(touchDown:)
               forControlEvents:UIControlEventTouchDown];
可以很显然看到action:@selector(touchDown:)这里,从文档入手,我们来看看所谓的SEL是什么鬼?


Selector

A selector is the name used to select a method to execute for an object, or the unique identifier that replaces the name when the source code is compiled. A selector by itself doesn’t do anything. It simply identifies a method. The only thing that makes the selector method name different from a plain string is that the compiler makes sure that selectors are unique. What makes a selector useful is that (in conjunction with the runtime) it acts like a dynamic function pointer that, for a given name, automatically points to the implementation of a method appropriate for whichever class it’s used with. Suppose you had a selector for the methodrun, and classes Dog,Athlete, and ComputerSimulation (each of which implemented a methodrun). The selector could be used with an instance of each of the classes to invoke itsrun method—even though the implementation might be different for each.

一个选择器是一个用来选择对象执行方法的名称,或者是一个独一无二的标志符当源码被编译的时候用作替换。一个选择器本身是不做任何事情的。它简单地标志一个方法。唯一的方法区别一个选择器和一个普通文本编译器会保证选择器是唯一的。使得选择器变得非常好价值(在runtime的时候联结)它表现得像一个动态方法指针,对于一个给定的名字,自动地指向类的一些合适的方法的实现。假设你有一个run的选择器,一个类Dog,选手,和ComputerSimulation(每一个都实现了run方法)。选择器能够被使用通过每一个类的实例去调用它的run方法 — 即使实现可能是不一样的(唯一的概念在这里,并不是说这个方法是唯一的,而是这个方法名字是unique的)


选择器是用SEL来表示的,并有两种方法来获取选择器:

文档写的分别是:

编译期间:

    SEL aSelector  = @selector(methodName);

运行期间:

    SEL aaSelecort = NSSelectorFromString(@"methodName");

而点进去NSSelectorFromString里面一看,可以发现在NSObjCRuntime.h中有这样一段宏定义:

FOUNDATION_EXPORT SEL NSSelectorFromString(NSString *aSelectorName);

还有反过来的,通过SEL取NSString的:

FOUNDATION_EXPORT NSString *NSStringFromSelector(SEL aSelector);

区别如期所述,下面的直达runtime才会知道该选择器的存在。



还可以使用相关方法直接调用SEL方法:

    [self performSelector:aSelector];
    [self performSelector:aSelector onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO];

点进入方法一看是定义在NSObject(及其相关的类目方法)上的方法,iOS同时也提供了相似的很多方法:




下面参考资料的一些解释非常到位:

并且提到了一点,SEL的定义是:

 typedef struct objc_selector *SEL

这个可是怎么点都点不出来的哦。


C语言对于函数名使用函数指针来处理的,熟悉或者懂得C的人就会知道,函数和对象变量一样也是有地址的。但是iOS中对于函数却没有像C使用地那么简便而是引入了SEL类型的选择器这个概念,而本质上和C的函数指针却是一个样,用!地!址!

先来看看C/C++中:

int test(int val)
{
<span style="white-space:pre">	</span>return val+1;
}
int (* c_func)(int val); //定义一个函数指针变量c_func = add ; //把函数addr地址直接赋给c_func
而Objective-C:

@interface foo
-(int)add:int val;
@end
SEL class_func ; //定义一个类方法指针class_func = @selector(add:int);
用习惯了C/C++等语言的人就会惊呆了说:OC实在太怪异了!   实际上,也的确怪异,用  “ @ ”  这个符号,来代表“寻找”, 即@Selector(myFunction:) 寻找当前类(类系)中方法myFunction:。


关于Selector 另外一个很重要的概念就一定会被提到: Target-Action 模式~!  将会在别的学习篇章继续学习。



参考:

Reference - 1:非常好  http://mobile.51cto.com/hot-431728.htm

Reference - 2: 深入    http://blog.csdn.net/fengsh998/article/details/8612969




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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值