对Objectiv-C的一些指针的理解

作者: LemonFan | 来源:发表于2017-04-04 17:09 被阅读80次

    objc_class

    首先了解两个重要类型,id和class
    id 与 Class,在 <objc/objc.h> 中可以找到两者定义

    // An opaque type that represents an Objective-C class.
    typedef struct objc_class *Class;
    // A pointer to an instance of a class.
    typedef struct objc_object *id;
    

    id 与 Class 都是指向结构体的指针。

    id与Class的结构体区别:

    //-----id 的结构体 ------
    struct objc_object {
        Class isa  OBJC_ISA_AVAILABILITY;
    };
    
    //-----Class的结构体
    struct objc_class {
        Class isa  OBJC_ISA_AVAILABILITY;
    
    #if !__OBJC2__
        //指向该类的父类
        Class super_class                                        OBJC2_UNAVAILABLE;
        //一个 C 字符串,指示类的名称。我们可以在运行期,通过这个名称查找到该类(通过:id objc_getClass(const char *aClassName))或该类的 metaclass(id objc_getMetaClass(const char *aClassName))
        const char *name                                         OBJC2_UNAVAILABLE;
        //类的版本信息,默认初始化为 0。我们可以在运行期对其进行修改(class_setVersion)或获取(class_getVersion)。
        long version                                             OBJC2_UNAVAILABLE;
        //供运行期使用的一些位标识。
        long info                                                OBJC2_UNAVAILABLE;
        //该类的实例变量大小
        long instance_size                                       OBJC2_UNAVAILABLE;
        //指向 objc_ivar_list 的指针,存储每个实例变量的内存地址
        struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
        //与 info 的一些标志位有关,如果 info 设置了 CLS_CLASS 则 objc_method_list  存储实例方法,如果设置的是 CLS_META 则存储类方法
        struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
        //指向 objc_cache 的指针,用来缓存最近使用的方法,以提高效率
        struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
        //objc_protocol_list 的指针,存储该类声明要遵守的正式协议。
        struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
    #endif
    
    } OBJC2_UNAVAILABLE;
    
    

    isa:是一个 objc_class 类型的指针。
    objc_object可以这样写:

    typedef struct objc_object {
        objc_class isa;
    } *id;
    

    Class 是一个 objc_class 结构类型的指针;而 id(任意对象) 是一个 objc_object 结构类型的指针,其第一个成员是一个 objc_class 结构类型的(isa)指针。

    objc_object对象创建时,运行时系统会在类的方法列表及父类的方法列表中去寻找与消息对应的selector指向的方法,找到后即运行这个方法。

    类对象所属的类型(也就是isa指针所指向的类型)是另外一个类型,叫做元类(metaclass),用来表述类对象本身所具备的元数据,“类方法”就定义在此处。

    实例对象的isa指针.png

    objc_selector

    typedef struct objc_selector *SEL;      
    
    //这一点是猜测的在runtime的源码内没有找到具体的objc_selector定 
    struct objc_selector{  
    void *sel_id;  
    const char *sel_types;
    };
    

    NSLog(@"SEL=%s",@selector(print))

    会输出为 SEL=print,SEL返回方法名。
    所以我觉得 SEL 理解为一个 char* 指针。SEL用来存储方法的编号,方便系统查询方法。


    IMP指针

    IMP指针它是指向一个方法实现的指针,每一个方法都有一个对应的IMP

    
    #if !OBJC_OLD_DISPATCH_PROTOTYPES
    typedef void (*IMP)(void /* id, SEL, ... */ ); 
    #else
    typedef id (*IMP)(id, SEL, ...); 
    #endif
    
    

    IMP 的含义:IMP 是一个函数指针,这个被指向的函数包含一个接收消息的对象id(self 指针), 调用方法的选标 SEL (方法名),以及不定个数的方法参数,并返回一个id。也就是说 IMP 是消息最终调用的执行代码,是方法真正的实现代码 。


    objc_method

    typedef struct objc_method *Method;
    
    typedef struct objc_ method {
        SEL method_name;
        char *method_types;
        IMP method_imp;
    };
    

    一个方法 Method,其包含一个方法选标 SEL – 表示该方法的名称,一个types – 表示该方法参数的类型,一个 IMP - 指向该方法的具体实现的函数指针

    相关文章

      网友评论

        本文标题:对Objectiv-C的一些指针的理解

        本文链接:https://www.haomeiwen.com/subject/ebczottx.html