简述
OC是一种运行时语言,它将静态语言在编译与链接做的事情延迟到运行时进行处理,这样我们就可以将方法随意转发给我们想要的对象以及随意交换方法的实现,这就意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码。
常见的三种定义
id定义
typedef struct objc_object *id;
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
NSObject定义
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
Class定义
typedef struct objc_class *Class;
由此可以看出Class其实就是指向objc_class的结构体指针
struct objc_class {
Class isa ;
#if !__OBJC2__
Class super_class;//指向该类的父类,如果该类已经是最顶层的根类(如NSObject或NSProxy),则super_class为NULL。
const char *name;
long version;
long info;
long instance_size;
struct objc_ivar_list *ivars;
struct objc_method_list **methodLists;
struct objc_cache *cache;//用于缓存最近使用的方法
struct objc_protocol_list *protocols;
#endif
} OBJC2_UNAVAILABLE;
1.类对象中的 isa 指向类结构被称作 metaclass,metaclass 存储类的static类成员变量与static类成员方法(+开头的方法);
2.实例对象中的 isa 指向类结构称作 class(普通的),class 结构存储类的普通成员变量与普通成员方法(-开头的方法);
参考链接
方法执行的过程:
向一个对象发送消息时,runtime会在这个对象所属的这个类的方法列表中查找方法。
向一个类发送消息时候,会在这个类的meta_class的方法列表中查找。
meta_class概念:
以 NSArray *array = [NSArray array] 为例:
+array消息发送给NSArray类,而这个类也是对象,那么该对象中就含有objc_object指针,它包含一个指向其类的一个isa指针,那么该isa又指向什么?
猜想:该isa指针必须指向一个包含这些类方法的一个objc_class结构体?
这就引入了meta_class的概念,
meta_class之所以重要是因为它存储着一个类的所有类方法,每个类都会有一个单独的meta_class,每个类的类方法基本不可能完全相同。
既然meta_class 也是一个类,也可也发送消息,那么他的isa指向的是什么?为了不让这种结构无限延伸下去,object_c 设计者将所有的meta_class指向基类的meta_class作为自己的所属类,而基类的meta_class指向它自己形成一个完美的闭环。