首先看下概念
实例对象:就是我们通常的类的实例化的对象比如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 最后找到消息进行调用
网友评论