一、基础概念
1.理解:实例对象、类、元类、根元类
(1)实例对象
实例对象是我们对类对象alloc或者new操作时所创建的,在这个过程中会拷贝实例所属类的成员变量,但并不拷贝类定义的方法。其中cache和bits的解释可参考链接,这里不做详细解释
struct objc_class : objc_object {
// Class ISA;
Class superclass;
cache_t cache; // formerly cache pointer and vtable
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
class_rw_t *data() {
return bits.data();
}
}
(2)类
类是面向对象里面的重要概念,具有封装、继承、多态这三个特征。这里不谈面向对象的类的基础概念,类在OC中是以结构体的形式实现的,是一个指向objc_class的结构体指针,以下是在iOS中实现类的结构。
typedef struct objc_class *Class;
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY; // isa指针,指向该类的元类(metaclass)
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE; // 父类
const char *name OBJC2_UNAVAILABLE; // 类名
long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0
long info OBJC2_UNAVAILABLE; // 类信息,供运行期使用的一些位标识
long instance_size OBJC2_UNAVAILABLE; // 该类的实例变量大小
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 该类的成员变量列表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定义的列表
struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法缓存
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 协议链表
#endif
} OBJC2_UNAVAILABLE;
(3)元类
元类实际上也是类,用于描述类对象的类,不过元类存储的是跟类信息相关的的例如、类方法。
(4)根元类
根元类简单来说可以理解为就是NSObject。
上面的元类和根类可能说的不够清楚,下面借鉴两张别人的图来说明以下整体的关系
为了验证上面的关系图,我用代码和地址输出来验证一下:
通过上图,可以看出,我一共参照了四个实例对象,分别是fromview、vc、fromObj和obj,其中fromView继承于UIview,fromObj继承于NSObject。在输出结果中可以看到,四个实例的根源类地址相同,最后的obj这个对象的父类指针为空,obj的元类和根元类的父类指向同一个地址。obj的根元类的根元类指向同一地址,完全印证了上面的关系图。 参考文章链接