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库之间对象,控制之间通讯都是在这个基础构建的。 

辛苦的劳动,转载请注明出处,谢谢……

http://www.cnblogs.com/kubixuesheng/p/4321233.html

时间: 2024-12-30 08:10:07

objective-c中的@selector()和 c /c++的函数指针的相关文章

Android中的Selector的用法

http://blog.csdn.net/shakespeare001/article/details/7788400 Android中的Selector主要是用来改变ListView和Button控件的默认背景. 新建mylist_view.xml文件后,可以根据项目需求,在其内部定义为自己想要的样式了,主要属性如下: <?xml version="1.0" encoding="utf-8" ?> <selector xmlns:android=

ios开发-iOS开发中 unrecognized selector sent to instance 的问题

问题描述 iOS开发中 unrecognized selector sent to instance 的问题 新人入门求助: 在storyboard的view里面添加一个TableView再在TableView里面添加一个TableViewCell之后,建立 一个dataSource和Delegate的outlet之后,点击运行,就出现unrecognized selector sent to instance 这个问题,全过程都在storyboard上完成的,还没有编写代码. 解决方案 自己遇

listview-Android 中 ListView selector 不能运行

问题描述 Android 中 ListView selector 不能运行 我使用list selector,但是不能很好的运行.点击list item后可以获得效果,但是在点击item之前没有任何效果出现.下面是 selector 的代码: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/

objective-C中的Class(类类型),Selector(选择器SEL),函数指针(IMP)

今天在园子里看到了一篇牛文"Objective-C 2.0 with Cocoa Foundation--- 5,Class类型,选择器Selector以及函数指针",讲得十分精彩,忍不住把它的代码加上注释整理于此,以便日后查看. 个人体会:obj-C中的"Class类型变量"比c#中的Object基类还要灵活,可以用它生成任何类型的实例(但是它又不是NSObject).而选择器SEL与函数指针IMP,如果非要跟c#扯上关系的话,这二个结合起来,就点类似c#中的反射

qmap-QT Qmap 在一个函数中定义,怎么在另一个函数中遍历

问题描述 QT Qmap 在一个函数中定义,怎么在另一个函数中遍历 50C void address_pool::set_address_pool(QString get_IP){ QString ip; ip= get_IP; qDebug()<<""IP""<<ip; QStringList str=ip.split(""); QStringList strlist= str.at(0).split("&qu

在C#中动态调用native dll的导出函数

动态|函数 在 C++ 中我们能够通过 LoadLibrary,  GetProcAddress 来动态调用 dll 的导出函数.在 C# 中也能够用这样的方式吗?在 DotNet 2.0 里面这样是可以的, 这完全得益于 2.0新增的一个函数Marshal.GetDelegateForFunctionPointer 方法 此方法在 .NET Framework 2.0 版中是新增的. 将非托管函数指针转换为委托. 实例代码如下: public delegate int MsgBox(int h

C#中使用网络函数 (第一部分 用户函数)[翻译]

函数|网络 本文将着重介绍Win32 API库中涉及网络管理的函数.首先我要讲一讲在.Net框架中管理用户的两个方法,第一种是Active Directory方法,这种方法要求你安装Active Directory.如果你打算管理一个小网络上的用户,或者一个未安装Active Directory的独立工作站,为了管理用户而安装Active Directory显得有些不值得.另外一种方法则是这篇文章所要讲到的--使用Win32 API库函数.在这篇文章中,我将介绍如何使用C# 添加.删除和修改用户

C++中的函数指针与函数对象的总结

以下是对C++中的函数指针与函数对象的使用进行了详细的分析介绍,需要的朋友可以参考下   篇一.函数指针函数指针:是指向函数的指针变量,在C编译时,每一个函数都有一个入口地址,那么这个指向这个函数的函数指针便指向这个地址. 函数指针的用途是很大的,主要有两个作用:用作调用函数和做函数的参数. 函数指针的声明方法:数据类型标志符 (指针变量名) (形参列表): 一般函数的声明为: int func ( int x );而一个函数指针的声明方法为:int (*func) (int x);前面的那个(

php中解析带中文字符的url函数分享

 这篇文章主要介绍了php中解析带中文字符的url函数分享,本文直接给出实现代码,重点是对rawurlencode函数的使用上,需要的朋友可以参考下     很多时候,在书写网页应用程序时候,会遇到中文和其他字符冲突的问题,例如有的url链接中包含中文字符,那么在使用wget/curl/file_get_contents等等获取信息时候会直接撞上一个大大的"404",会很无语. 这里写了一个小函数来解决这个问题,只是限于在path中进行解析而已,涉及到的相关函数使用大家可以查看手册就行