Class 类型、Selector 选择器、SEL 类型、函数指针

 

一、Class 类型

 

  • 机制:一个类在正确编译后,在这个被正确编译好的类里面,存在一个isa指针,用于存储类的方法及变量信息,这个isa指针是id类型。可以通过一个普通的字符串可能获取到这个Class类型对象,也可以通过此类的对象获取到此类的Class类型对象,获取到Class类型对象后,可以按类实例化后的对象一样使用它。在程序runtime可以通过类的Class类型对象获取到类实例化后的对象,也可以动态的获取在编译阶段无法确定的对象。

  • 因为,在类里面存储了类的所有信息,所以,可以通过类的名称或类的对象获取到Class类型对象。当然,也可以获取到超类的Class类型对象。

     1 // 通过类名称或对象,向此类或者对象发送class消息,获取此类的Class类型对象
     2 Class class = [类名称或对象 class];
     3 // 通过类名称或对象,向此类或者对象发送superclass消息,获取此类的超的Class类型对象
     4 Class superClass = [类名称或对象 superclass];
     5 // 通过类名称字符串,获取此类的Class类型对象
     6 Class class = NSClassFromString(类名称字符串);
     7 // 通过Class类型对象,获取此类的名称字符串
     8 NSString *classname = NSStringFromClass(Class 参数);
     9 // 向类对象发送消息,获取类的类名称,classname是一个固定参数,详细参考classname实现源码
    10 NSString *classname = [classobject classname];

     

二、Selector 选择器

  • 机制:选择器Selector是用于表示方法的,会根据方法的名称(参数序列),确定一个唯一的身份证明(其实,就是一个整数),(摸不准/*在不同的类里面相同名称相同声明的方法,其身份证明是相同的)。在runtime就不用对方法的名称进行比较,以确定要执行的是哪一个方法,只要通过一个整数就可以定位到相应的方法,然后就可以找到相应方法的入口地址,就可以执行方法了。在OC中消息的执行(方法的执行)与C语言直接找到函数地址入口方式相比,OC的消息机制从效率上讲是比较低下的。虽然,OC使用了Selector选择等方式进行寻找,总是要花费时间的。OC是兼容C语言的,也就是说可以使用C的函数指针方式,增加效率。当要求效率时,比如,当在一个大循环里,要使用某一功能时,就放弃对某一单一对象发送消息的方式(Selector),从而使用函数指针,这样就有和C一样的效率了。

三、SEL 类型

  • 在Selector选择器已经说了,在编译的时候,会根据方法的名字及参数序列,确定一个唯一的身份证明,这个身份证明就是一个SEL类型,可以通过方法名字取得方法的ID(SEL类型对象),也可以通过方法名称的字符串取得SEL类型对象。反之,也可以通过SEL类型对象(ID)取得方法名字。如下:
    1 // 通过方法名称,获取此方法的SEL类型对象
    2 SEL 变量名 = @selector(方法名称); 
    3 // 通过方法名称字符串,获取此方法的SEL类型对象
    4 SEL 变量名 = NSSelectorFromString(方法名称字符串);
    5 // 通过方法的SEL类型对象及参数,获取方法名称 
    6 NSString *变量名 = NSStringFromSelector(SEL 参数);
    7 // 通过SEL类型对象,获取到此方法的方法名称
    8 NSString *变量名 = [SEL methodname];

     

  • 调用方式
    1 // 对象 -- 接收器
    2 [对象 performSelector: SEL类型变量 withObject: 参数1 withObject: 参数2 ...];

     

  • 好处:增加其方法使用的灵活性,可以通过配置文件(文本文件、XML文件)指定程序要执行的方法,在runtime读取配置文件,将方法名称或方法名称字符串转换成SEL类型对象,通过发送消息执行。由于,OC中寻找方法是通过ID(一个整型值),相比匹配字符串寻找方法要有效率得多。 

四、函数指针

  • 格式
    1 // C函数指针,id -- 接收者对象,SEL -- 方法的SEL类型对象,NSString * -- 方法参数(自定义)
    2 void (*func)(id, SEL, NSString *);
    3 // OC
    4 IMP funoc;

    PS: 用法和C一样。

  • 例子
    1 id cla = [[ClassE alloc] init];
    2 SEL funoc = @Selector(fun);
    3 void (*func)(id, SEL, NSString *);
    4 func = (id, SEL, NSString *) [cla methodForSelector: funoc];
    5 func(cla, funoc, @"test");

 

  • 参数 (在OC中,函数指针的前两个参数,即:id与SEL是必须的,剩下的参数是由函数指针的参数序列决定)
      1. id -- 是一个id类型,是指消息的接收者对象。在runtime实际上id就是self对象,因为要从某个对象发送消息。
      2. SEL -- 是一个SEL类型,是指方法的ID(方法的身份证明,一个整型),在消息发送过程中,通过_cmd方法本身的SEL(方法ID)。也就是说在方法的定义体里面,可以通过_cmd获取方法本身的ID。
      3. NSString* -- 自定义参数。
posted @ 2015-08-13 11:02  naray  阅读(847)  评论(0编辑  收藏  举报