美文网首页
objc runtime 源码解析

objc runtime 源码解析

作者: sakuragi | 来源:发表于2016-06-12 11:33 被阅读477次

    类和对象是如何定义的

    • An opaque type that represents an Objective-C class.

      typedef struct objc_class *Class
      

      可以看出,在OC中,类其实是一个objc_class的结构体指针

    struct objc_class:objc_object {
    Class superclass;//父类
    const char *name;//类名
    uint32_t version //版本号,默认为0
    uint32_t info;//信息
    uint32_t instance_size;//实例大小
    struct old_ivar_list *ivars;//成员变量列表
    struct old_method_list methodLists //方法列表(这里为什么要两个)?
    Cache cache;//方法缓存
    struct old_protocol_list *protocols //协议列表
    ...
    }

    我们再看看```objc_object```的定义
    

    struct objc_object {
    private:
    isa_t isa;
    public:
    Class ISA();
    Class getIsa();
    }

    在OC中,所有的类本身也是一个对象,这个对象的Class里面也有一个isa指针,它指向*metaClass*。
    - 对象
      > Represents to an instance of a class
    
    

    struct objc_object {
    Class isa OBJC_ISA_AVAILABILITY;
    }

    #id
    >A pointer to an instance of a class
    
    

    typedef struct objc_object *id;

    是一个objc_object类型的结构体指针
    在OC中,我们经常声明一个```id obj```的对象,这里转换一下其实是这样一行代码``` struct objc_object *obj```。可以看出 obj被声明为的一个结构体指针。obj指针指向的类型是一个结构体objc_object。objc_object结构体中有一个 isa指针,isa指针指向一个objc_class的类型。
    #SEL
    >An opaque type that  represents a method selector.
    
    

    type struct objc_selecotr *SEL;

    在runtime的源码中,我们没有找到```objc_selector```的定义
    首先我们必修明确一点,SEL的拥有者是我们的method,一个method的selector用于表示运行时这个method的实现,我们可以通过一段代码来看看一个
    
    • (void) method {}

    SEL sel = @selector(method);
    NSLog(@"sel = %p",sel);

    >sel : 0x100014ffa
    
    在编译期,系统会根据方法名,参数列表生成一个唯一的标识,这个标识是int型的SEL.
    因此,在同一个类中,或者是他的继承体系中,只能存在一个方法名相同的方法,就算参数类型不同都不行,而在C++或者java中,允许方法名相同而参数类型不一样的方法同时存在。
    #IMP
    >A pointer to the function of a method implementation
    
    

    typedef id (*IMP)(id,SEL, ...);

    
    [函数指针百度百科的定义](http://baike.baidu.com/link?url=nxL0nYcQ4dRDkhbYBo_sGVOzWSlW3_jOP-eMmLNVVwPr_GWT7pW711bU7u_KcK-aAHR_nQ8gpssHCkF9kfTtAK)
    可以看出,IMP是一个函数指针,第一个参数id是指向self的指针,如果是类实例方法,那么指向实例的地址,如果是类方法,则指向元类的地址。第二个参数是选择器selector,后面的是参数列表。

    相关文章

      网友评论

          本文标题:objc runtime 源码解析

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