📚苹果runtime

iOS实例对象和类对象

2018-03-21  本文已影响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 最后找到消息进行调用

上一篇 下一篇

猜你喜欢

热点阅读