类
什么是元类
-
我们都知道 对象的
isa是指向类,类的其实也是一个对象,可以称为类对象,其isa的位域指向苹果定义的元类 -
元类是系统给的,其定义和创建都是由编译器完成,在这个过程中,类的归属来自于元类 -
元类是类对象 的类,每个类都有一个独一无二的元类用来存储类方法的相关信息。 -
元类本身是没有名称的,由于与类相关联,所以使用了同类名一样的名称
isa走位
对象的isa—>类(也叫类对象)
类的isa—>元类
元类的isa—>NSObject(根元类)
NSObject的isa —>NSObject(他自己)
*内存中有且仅有一个NSObject,根元类的元类指向他自己
isa走位.png
objc_class & objc_object
对象和类都有isa,其中有什么联系:
- 类的
isa是有objc_class定义的指针类型 -
objc_class是一个结构体,在iOS中,所有的class都是以objc_class为模版创建的
struct NSObject_IMPL {
Class isa;
};
typedef struct objc_class *Class;
objc_class的定义:
struct objc_class : objc_object {//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() const {
return bits.data();
}
void setData(class_rw_t *newData) {
bits.setData(newData);
}
void setInfo(uint32_t set) {
ASSERT(isFuture() || isRealized());
data()->setFlags(set);
}
void clearInfo(uint32_t clear) {
ASSERT(isFuture() || isRealized());
data()->clearFlags(clear);
}
// set and clear must not overlap
void changeInfo(uint32_t set, uint32_t clear) {
ASSERT(isFuture() || isRealized());
ASSERT((set & clear) == 0);
data()->changeFlags(set, clear);
}
objc_class 与 objc_object的关系:
- 结构体类型
objc_class继承自objc_object类型,其中objc_object也是一个结构体,且有一个isa属性,所以objc_class也拥有了isa属性
⬇️ -
mian.cpp底层编译文件中,NSObject中的isa在底层是由Class定义的,其中class的底层编码来自objc_class类型,所以NSObject也拥有了isa属性
⬇️ -
NSObject是一个类,用它初始化一个实例对象objc,objc满足objc_object的特性(即有isa属性),主要是因为isa是由NSObject从objc_class继承过来的,而objc_class继承自objc_object,objc_object有isa属性。所以对象都有一个isa,isa表示指向,来自于当前的objc_object
⬇️ -
objc_object(结构体) 是 当前的 根对象,所有的对象都有这样一个特性objc_object,即拥有isa属性
面试题:
objc_object 与 对象的关系
-
所有的对象 都是以
objc_object为模板继承过来的 -
所有的对象 是 来自
NSObject(OC),但是真正到底层的 是一个objc_object(C/C++)的结构体类型
【总结】 objc_object与 对象的关系是继承关系
内存
- 与内存相关的名词解析
对象指针:指向类的成员的指针。在C++中,可以说明指向类的数据成员和成员函数的指针。
对象内存地址:对象存储位置的地址,相当于门牌号一样
指针:指针变量就是一个变量,这个变量本身要存储在内存中,指针变量所在内存中存储的就是这个指针变量所指向的地址
指针地址:本身也是指针变量,此变量指向的地址中存储的是指针的地址
//对象
CJLPerson *p1 = [CJLPerson alloc]; // p1 是指针
CJLPerson *p2 = [CJLPerson alloc];
NSLog(@"%d -- %p", p1, &p1);
NSLog(@"%d -- %p", p2, &p2);
-
p1、p2是指针,p1是 指向[CJLPerson alloc]创建的空间地址,即内存地址,p2同理 -
&p1、&p2是 指向p1、p2对象指针的地址,这个指针就是二级指针
指针详解.png














网友评论