1、SEL类型

例子:

SEL say;
       SEL skin;

Objective-C 在编译的时候, 会根据方法的名字(包括参数序列),生成一个用 来区分这个方法的唯一的一个 ID,这个 ID 就是 SEL 类型的。我们需要注意的是,只要方法的名字(包括参数序列)相同,那么它们的 ID 都是相同的。就是 说,不管是超类还是子类,不管是有没有超类和子类的关系,只要名字相同 那么 ID 就是一样的。

在 程序执行的时候,我们可以方便的通过方法的名字,获取到方法的 ID 也就是我们所说的 SEL, 反之亦然。具体的使用方法如下:

1    SEL 变量名 = @selector(方法名字);
       2    SEL 变量名 = NSSelectorFromString(方法名字的字符串);
       3    NSString *变量名 = NSStringFromSelector(SEL 参数);
其中第 1 行是直接在程序里面写上方法的名字,第 2 行是写上方法名字的字符串,第 3 行是通 过 SEL 变量获得方法的名字。我们得到了 SEL 变量之后,可以通过下面的调用来给一个对象发 送消息:

[对象 performSelector:SEL 变量 withObject:参数 1 withObject:参数 2];
这样的机制大大的增加了我们的程序的灵活性,我们可以通过给一个方法传递 SEL 参数,让这 个方法动态的执行某一个方法;我们也可以通过配置文件指定需要执行的方法,程序读取配置文 件之后把方法的字符串翻译成为 SEL 变量然后给相应的对象发送这个消息。
从效率的角度上来说,执行的时候不是通过方法名字而是方法 ID 也就是一个整数来查找方法, 由于整数的查找和匹配比字符串要快得多,所以这样可以在某种程度上提高执行的效率。

2、IMP类型

例子:

void(*setSkinColor_Func) (id, SEL, NSString*);//定义一个函数指针(传统C语言的处理方式)

IMP say_Func;//定义一个IMP方式的函数指针(obj-C中推荐的方式)

说白了IMP就是实现方法,给一个方法起个名字,实现动态调用,不用再使用[对象 message]的方式。

IMP 的定义如下:

typedef id    (*IMP)(id, SEL, ... );
这个格式正好和我们在第一行代码里面的函数指针的定义是一样的。
我们取得了函数指针之后,也就意味着我们取得了执行的时候的这段方法的代码的入口,这样我 们就可以像普通的 C 语言函数调用一样使用这个函数指针。当然我们可以把函数指针作为参数 传递到其他的方法,或者实例变量里面,从而获得极大的动态性。我们获得了动态性,但是付出 的代价就是编译器不知道我们要执行哪一个方法所以在编译的时候不会替我们找出错误,我们只 有执行的时候才知道,我们写的函数指针是否是正确的。所以,在使用函数指针的时候要非常准 确地把握能够出现的所有可能,并且做出预防。尤其是当你在写一个供他人调用的接口 API 的 时候,这一点非常重要。
3、Class

类在 Objective-C 也为我们准备了类似的机制, Class 类型。当一个类被正确的编译过后,在这个编译成功的类里面,存在一个变量用于保存这 个类的信息。我们可以通过一个普通的字符串取得 这个 Class,也可以通过我们生成的对象取 得这个 Class。Class 被成功取得之后,我们可以把这个 Class 当作一个已经定义好的类来使用 它。这样的机制允许我们在程序执行的过程当中,可以 Class 来得到对象的类,也可以在程序 执行的阶段动态的生成一个在编译阶段无法确定的一个对象。
因为 Class 里面保存了一个类的所有信息,当然,我们也可以取得一个类的超类。关于 Class 类型,具体的使用格式如下:
1    Class 变量名 = [类或者对象 class];
2    Class 变量名 = [类或者对象 superclass];
3    Class 变量名 = NSClassFromString(方法名字的字符串);
4    NSString *变量名 = NSStringFromClass(Class 参数);
第一行代码,是通过向一个类或者对象发送 class 消息来获得这个类或者对象的 Class 变量。 第二行代码,是通过向一个类或者对象发送 superclass 消息来获得这个类或者对象的超类的
Class 变量。
第三行代码,是通过调用 NSClassFromString 函数,并且把一个字符串作为参数来取得 Class 变量。这个在我们使用配置文件决定执行的时候的类的时候,NSClassFromString 给我们带来 了极大的方便。
第四行代码,是 NSClassFromString 的反向函数 NSStringFromClass,通过一个 Class 类 型作为变量取得一个类的名字。
当我们在程序里面通过使用上面的第一,二或者第三行代码成功的取得一个 Class 类型的变量, 比如说我们把这个变量名字命名为 myClass,那么我们在以后的代码种可以把 myClass 当作 一个我们已经定义好的类来使用,当然我们可以把这个变量作为参数传递到其他的方法当中让其 他的方法动态的生成我们需要的对象。

几个重要的辅助函数,可以在使用过程中起到很好的辅助作用,尤其是在动态编译等起到了比较大的作用。

我们可以通过NSObject的一些方法获取运行时信息或动态执行一些消息:

class   返回对象的类;

isKindOfClass 和 isMemberOfClass检查对象是否在指定的类继承体系中;

respondsToSelector 检查对象能否相应指定的消息;

conformsToProtocol 检查对象是否实现了指定协议类的方法;

methodForSelector  返回指定方法实现的地址。

performSelector:withObject 执行SEL 所指代的方法。

Objective-C中的SEL、IMP和Class类型的更多相关文章

  1. Method Swizzle黑魔法,修改 ios 系统类库方法 SEL IMP

    Method Swizzle黑魔法,修改 ios 系统类库方法   版权声明:本文为博主原创文章,未经博主允许不得转载. 一般来说,系统提供的方法已经足够开发了,但是有的时候有些需求用普通方法不好做. ...

  2. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  3. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  4. OC中的SEL解析

    OC中的SEL对象即selector对象,用来保存一个方法的地址.下面通过一个Demo来解析SEL的原理.创建一个Person类,Person.h中: #import <Foundation/F ...

  5. Objective-C中的SEL (转载)

     SEL 在Objective-C中,SEL是选择器(selector)的一个类型.选择器就是指向方法的一个指针,读者可以简单理解为程序运行到这里就会执行指定的方法,可以这样定义一个选择器: SEL  ...

  6. objective C中的字符串NSStirng常用操作

    objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的 ...

  7. 在 SharePoint Server 2013 中配置建议和使用率事件类型

    http://technet.microsoft.com/zh-cn/library/jj715889.aspx 适用于: SharePoint Server 2013 利用使用事件,您可以跟踪用户与 ...

  8. DB2中字符、数字和日期类型之间的转换

    DB2中字符.数字和日期类型之间的转换 一般我们在使用DB2或Oracle的过程中,经常会在数字<->字符<->日期三种类 型之间做转换,那么在DB2和Oracle中,他们分别 ...

  9. oracle,如何查看视图结构,获得视图中的字段名称、字段类型、字段长度等。

    需要获得一个视图中的字段名称.字段类型.字段长度等信息,该如何编写sql语句.通过select * from user_views可以获得给定用户下所有的视图名称了,但是没找到如何获取视图结构的解决方 ...

  10. Net Framework中的提供的常用委托类型

    .Net Framework中的提供的常用委托类型   .Net Framework中提供有一些常用的预定义委托:Action.Func.Predicate.用到委托的时候建议尽量使用这些委托类型,而 ...

随机推荐

  1. PDF417码

    PDF417码是由留美华人王寅敬(音)博士发明的.PDF是取英文Portable Data File三个单词的首字母的缩写,意为“便携数据文件”.因为组成条码的每一符号字符都是由4个条和4个空构成,如 ...

  2. oracle序列详解

    tyle="margin:20px 0px 0px; font-size:14px; line-height:26px; font-family:Arial"> 序列: 是o ...

  3. 链接分析算法之:HillTop算法

      链接分析算法之:HillTop算法     Hilltop算法是由Krishna Baharat 在2000年左右研究的,于2001年申请专利,但是有很多人以为Hilltop算法是由谷歌研究的.只 ...

  4. 爬虫框架Scrapy

    前面十章爬虫笔记陆陆续续记录了一些简单的Python爬虫知识, 用来解决简单的贴吧下载,绩点运算自然不在话下. 不过要想批量下载大量的内容,比如知乎的所有的问答,那便显得游刃不有余了点. 于是乎,爬虫 ...

  5. cocos2dx进阶学习之CCLayer

    继承关系 CCLayer -> CCNode,CCTouchDelegate,CCAccelerometerDelegate,CCKeypadDelegate CCLayer在cocos2dx中 ...

  6. BZOJ 1611: [Usaco2008 Feb]Meteor Shower流星雨

    1611: [Usaco2008 Feb]Meteor Shower流星雨 Description 去年偶们湖南遭受N年不遇到冰冻灾害,现在芙蓉哥哥则听说另一个骇人听闻的消息: 一场流星雨即将袭击整个 ...

  7. 开机时进入 grub rescue>的解决方法

    本机是centOS7和win8的双系统 之前在win上把一个空的磁盘空间释放了 可能造成了grub的一些问题 具体还没有研究过 开机后无法正常进入grub引导画面 而是跳出一串英文+ grub res ...

  8. javascript使用消息框

    之前很多地方都用过alert,它的作用是弹出一个警告框,我们调用的方法是alert("输入的内容");其实更正确的写法是 window.alert("输入的内容" ...

  9. [置顶] android网络通讯之HttpClient4不指定参数名发送Post

    在HttpClient4之前都是通过List<NameValuePair>键值对的形式来向服务器传递参数 ,在4.0版本中在加入了不指定参数名发送数据的形式,利用StringEntity来 ...

  10. ASP.NET MVC 以Stream 下载文件

     1.0以Stream 下载文件 nl.fileid = Int32.Parse(id); //服务器上对应的id Stream stream = Lawsuit.DownLoad(nl);//服务器 ...