美文网首页📚苹果runtime
iOS实例对象和类对象

iOS实例对象和类对象

作者: 字母大师 | 来源:发表于2018-03-21 12:12 被阅读0次

    首先看下概念
    实例对象:就是我们通常的类的实例化的对象比如Obj * obj = [Obj new];,那么这个obj 就是一个实例对象
    类对象:这个时候是否有点奇怪,其实类也是一个对象,比如Obj 其实也是一个对象
    元类:其实就是 类对象的isa指向的类。

    点开#import <objc/objc.h> 点进去我们可以发现class与object在Objective-C的定义

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

    可以看到Class是一个objc_class结构类型的指针
    继续点击objc_class这个结构体,可以发现它的体现

    struct objc_class {
        Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
    
    #if !__OBJC2__
        Class _Nullable super_class                              OBJC2_UNAVAILABLE;
        const char * _Nonnull name                               OBJC2_UNAVAILABLE;
        long version                                             OBJC2_UNAVAILABLE;
        long info                                                OBJC2_UNAVAILABLE;
        long instance_size                                       OBJC2_UNAVAILABLE;
        struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
        struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
        struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
        struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
    #endif
    
    } OBJC2_UNAVAILABLE;
    

    可以看到类对象包含以下内容等


    image.png

    而objc_object 则是一个

    /// Represents an instance of a class.
    struct objc_object {
        Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
    };
    包含有一个isa指针
    

    我们可以用代码来看 新建一个Person类


    image.png

    我们可以看到


    image.png
    包含一个isa指针和_age成员变量,由此我们可知道,实例对象储存的信息如下
    image.png

    我们现在清楚,Objective-C的一个类也是一个对象。这意味着你可以发送消息给一个类
    由上可知,因为Objective-C中每个类本身也是一个对象。这意味着类结构必须以一个isa指针开始,为了调用类里的方法,类的isa指针必须指向包含这些类方法的类结构体。所以:
    元类是类对象的类
    我们可以用

    Class class = object_getClass([NSObject class]);
    

    获取 class为NSObject的元类对象
    因为每个类在内存中有且只有一个类对象,所以每个类在内存中也有且只有一个元类对象
    当你给对象发送消息时,消息是在寻找这个对象的类的方法列表
    当你给类发消息时,消息是在寻找这个类的元类的方法列表
    所以元类中存储的信息


    image.png

    借用网上大神的图:


    image.png

    我们可以总结出:
    实例对象的isa指向类对象,当调用对象方法,通过实例对象的isa 找到类对象,最终找到对对象方法进行调用
    类对象的isa指向元类,调用类方法,通过类对象中的isa找到元类,最终找到元类中的类方法进行调用
    当子类的对象要调用父类的对象方法,先通过子类的isa找到父类的class 然后通过superClass找到
    父类的class 最后找到消息进行调用

    相关文章

      网友评论

        本文标题:iOS实例对象和类对象

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