类
什么是元类
-
我们都知道 对象的
isa
是指向类,类
的其实也是一个对象
,可以称为类对象
,其isa的位域指向苹果定义的元类
-
元类是
系统给的,其定义和创建都是由编译器完成
,在这个过程中,类的归属来自于元类
-
元类
是类对象 的类,每个类都有一个独一无二
的元类用来存储类方法
的相关信息。 -
元类
本身是没有名称
的,由于与类相关联,所以使用了同类名一样
的名称
isa走位
对象的isa—>类(也叫类对象
)
类的isa—>元类
元类的isa—>NSObject(根元类
)
NSObject的isa —>NSObject(他自己
)
*内存中有且仅有一个NSObject,根元类的元类指向他自己
![](https://img.haomeiwen.com/i4127520/ff5700af9783d646.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
网友评论