objective-c中的@selector()和 c /c++的函数指针
先看tomcat里用到的代码:
//然后开始动画 //把图片放到animationImages,接受数组参数 self.tom.animationImages = arrayImage; //设置时间间隔,81张图,图多就播的时间稍微长,否则短 self.tom.animationDuration = arrayImage.count * 0.074; //设置重复次数 self.tom.animationRepeatCount = 1; //开始动画 [self.tom startAnimating]; //结束动画,应该等等再清空 [self.tom performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:self.tom.animationDuration];
最后一句代码,延迟加载 set 方法的过程。@selector(xxxx)的作用是找到名字为xxxx的方法。就是说去调用a对象的b方法,和[a b];的意思一样,但是这样更加动态一些。返回的类型是SEL,看方法说明的时候如果参数类型是SEL,那么就是要接受@selector(xxxx)返回的值。
回忆:
objective-c 语法快速过(5)中的SEL数据类型
每个类的方法列表都存储在类对象中,每个方法都有一个与之对应的SEL类型的数据,根据一个SEL类型的数据就可以找到方法的地址,进而调用方法。SEL类型的定义:
typedef struct objc_selector *SEL;
SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址。找到方法地址就可以调用方法,其实发送的消息就是SEL。
具体这objc_selector结构体是什么,取决与使用GNU的还是Apple的运行时, 在Mac OS X中SEL其实被映射为一个C字符串,可以看作是方法的名字,它并不指向具体方法实现(IMP类型才是)。
对于所有的类,只要方法名是相同的,产生的selector都是一样的。
看官方文档;
- (id)performSelector:(SEL)aSelector
把指定的消息发送给接收方,饼返回执行的结果,也就是说 perform(本身就有履行执行的意思)Selector :xxx,是执行名字为 xxx 方法的方法,只不过是间接去执行,通过 sel 参数(使用@selector(方法的名字)的返回sel 类型),找到方法。
看到这里,发现@selector(methodName)非常类似 c 语言的函数指针的概念。
C语言中,可以把函数名直接赋给一个函数指针,而OC的类不能直接应用函数指针,这样只能做一个@selector语法来取.它的return结果是一个SEL类型。这个类型本质是类方法的编号(函数地址)。
回忆函数指针:
函数也具有地址,指向函数的指针指向(保存)了函数代码起始处的地址,声明一个函数指针,必须先声明它指向的函数类型(返回类型和参量类型),声明指向函数的指针,函数指针可以作为另一个函数的参数,告诉第二个函数使用哪个函数。
void ToUpper(char *);//先声明函数 …… void (*p)(char *);//指针p是指向函数ToUpper的指针
即:(*p)也是一个函数,char*是它的参量,void是返回类型,表达式(*p)代替了函数名。因为*运算符优先级低于(),故必须加括号——(*p),省略掉圆括号意义就变了:
void * p(char *);//意思是p是一个函数,返回一个空指针类型
声明了函数指针,则可以用函数名表示函数的地址,当然指针也可以。函数指针最普遍的用法,是作为函数参数. 且只能指向函数都是相同类型的,可以用函数指针作为函数的参数,也能用函数名作为参数(函数名看作是函数地址),不能有函数数组!但是可以有函数指针的数组
再看 oc,取得selector值.
//object-c的选择器 @interface method -(int)add:(int) val; @end SEL fun ; //相当于定义一个方法指针 fun = @selector(add:);
注意;
可以用字符串来找方法
SEL 变量名 = NSSelectorFromString(方法名字的字符串);
可以运行中用SEL变量反向查出方法名字字符串
NSString *变量名 = NSStringFromSelector(SEL参数);
取得相应值后,怎么处理SEL值,这一点仍然与函数指针一样,就是执行它。SEL变量的执行,用performSelecor对象方法来执行.
[对象 performSelector:SEL变量 withObject:参数1 withObject:参数2];
selector的应用场合
是能让Objective-C动态调用方法的玩意.
是 object-c 的动态后绑定技术
可以通过字符串访问函数
selector本质是跟C的回调函数一样。主要用于两个对象之间进行松耦合的通讯.这种方法基本上整个Cocoa库之间对象,控制之间通讯都是在这个基础构建的。
欢迎关注
dashuai的博客是终身学习践行者,大厂程序员,且专注于工作经验、学习笔记的分享和日常吐槽,包括但不限于互联网行业,附带分享一些PDF电子书,资料,帮忙内推,欢迎拍砖!