runtime 学习笔记(一)

概述

     OC正是由于有了runtime才使得c语言具有了面向对象的能力,在程序的运行时刻,创建,检查,修改类、对象以及类、对象的方法。

    为什么会这么说?OC中的对象、类又到底是一个什么样的数据结构,对象、类又是如何用C来描述的呢?带着这样的问题,我们首先来看一下在OC中类的定义。

Class

    在objc/runtime.h中objc_class结构体的定义如下:

struct objc_class {

Class isaOBJC_ISA_AVAILABILITY;//isa指针指向Meta Class,因为objc类本身也是一个object(对象),为了处理这个关系,runtime创造了Meta Class,当一个类发送[NSObject alloc]这样消息时,实际上是把消息发送给Class object类对象

#if !__OBJC2__

Class super_classOBJC2_UNAVAILABLE;//父类

const char *nameOBJC2_UNAVAILABLE;//类名

long versionOBJC2_UNAVAILABLE;//类的版本信息,默认为0

long infoOBJC2_UNAVAILABLE;//类信息,供运行时使用的一些位表示

long instance_sizeOBJC2_UNAVAILABLE;//该类的实例变量大小

struct objc_ivar_list *ivarsOBJC2_UNAVAILABLE;//该类的成员变量的链表

struct objc_method_list **methodListsOBJC2_UNAVAILABLE;//方法定义的链表

struct objc_cache *cacheOBJC2_UNAVAILABLE;//方法缓存,对象接到一个消息会根据isa指针查找消息对象,这时会在methodLists中遍历,如果cache了,常用的方法调用时就能够提高调用的效率。

struct objc_protocol_list *protocolsOBJC2_UNAVAILABLE;//协议链表

#endif

} OBJC2_UNAVAILABLE;

在objc.h中有这样一个定义

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

typedef struct objc_class *Class;

即:OC当中任何一个类都是用objc_class这样一个结构体来描述的。

objc_object与id

    objc_object是一个类的实例结构体,objc/objc.h中objc_object是一个类的实例结构体定义如下:

struct objc_object {

Class isa OBJC_ISA_AVAILABILITY;

};

typedef struct objc_object *id;

    与objc_class相同,在OC当中用一个结构体描述一个对象;在向object发送消息的时候,runtime会根据object的isa指针找到这个实例的object所属于的类,然后在类的方法列表以及父类的方法列表中寻找对应的方法运行。

    id是一个objc_object结构类型的指针,这个类型的对象能够转换任何一种对象。

Meta Class

    大家可能注意到,一个对象的isa指针会指向它的类。然而在面向对象的世界里,一切都是对象,即:一个类也是一个对象,那么问题来了,那这个类对象它的类是谁呢(可能有点绕大家稍微理解一下这觉话)?类对象的isa指针又会指向哪里呢?

   为了解决这个问题,runtime创造了元类(Meta Class)。即一个类的是它元类的实例话,一个类的isa指针是指向它的元类。和对象一样,我们向一个类发送消息的时候,isa指针会在元类中以及元类的父类方法列表寻找对应的方法运行。

    既然一切都是对象那么元类也是对象,那么元类的类是谁?元类的isa指针指向哪里呢?下面这张经典的图完美了解释了一些,废话少说上图:


runtime 学习笔记(一)_第1张图片

    即任何一个元类都是根元类的对象,任何一个元类的isa指针都指向了根元类;而根元类的isa指针又指向了它自己;形成了一个闭环,这样就完美的诠释了面向对象的世界里万物皆对象的概念。(这张图,大家一定要好好的理解一下,如果今天看不懂,那么我给的建议是明天再看一遍,如果明天还看不懂,那就后天,如果还是不懂,那就过段时间再来看,如此反复,直到成功)

    好吧,到这里大家应该明白了,oc其实就是在用c的结构体来描述类和对象,通过一个isa指针指来指去完成了方法的调用,对于c系的同学来说应该不会有太大的难度。。。

后面会继续写关于runtime的知识。今天就先到这里吧,打卡,下班,回家。。。


顺道拜托,若文中有任何理解不正确的地方欢迎指出

你可能感兴趣的:(runtime 学习笔记(一))