zoukankan      html  css  js  c++  java
  • 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* -- 自定义参数。
  • 相关阅读:
    龙井和碧螺春的功效与作用
    064 01 Android 零基础入门 01 Java基础语法 08 Java方法 02 无参带返回值方法
    063 01 Android 零基础入门 01 Java基础语法 08 Java方法 01 无参无返回值方法
    062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用
    061 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 08 一维数组总结
    060 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 07 冒泡排序
    059 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 06 增强型for循环
    058 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 05 案例:求数组元素的最大值
    057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和
    056 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 03 一维数组的应用
  • 原文地址:https://www.cnblogs.com/naray/p/4726669.html
Copyright © 2011-2022 走看看