一、什么是类?
如果从数据结构来说。类其实就是升级版的结构体,在C语言的机构体中,只能定义属性,但不能定义方法,而类的升级,就是升级在,类不仅仅包含属性,还可以定制方法,其实就是一个可以实现某种功能的方法和属性的结合,例如可以定义一个分数类,这个类中,有总成绩、平均成绩两个属性,有加法和平均法两个方法,这就是一个类了,所以类的本质就是结构体,上一节也有例子进行佐证。
二、类的加载和初始化
如下图创建了三个类 person、student、animal三个类
类的加载:程序一运行就会加载类的一部分
+(void)load
当用到某个类的时候再加载全部,进行初始化
+(void)initialize
二、类在内存中的存储
类在创建的过程中,是如何在内存中存储的?
我们就以下图下图创建person1对象为例
执行该语句包含三部分 1.在代码区中加载Person类的所有代码 2在堆内存中创建Person类的类对象 ,然后根据Person类的类对象创建person实例对象 3.把实例对象person在堆中的地址赋值给存储在栈区的person1对象指针
其具体过程参照下图
由此我们可以得出以下结论
1、类其实分为两类
(1)类对象
注意 :当类被使用时每个类有且只有一个类对象
既然是“对象”,就有类型 其类型就是Class类型
所有的实例对象的isa都指向了“类对象”,类对象存储类类中
所有方法的函数指针(SEL),SEL 是一种专门存储函数指针的数据类型
(2)实例对象
注意:通过类对象创建实例对象,
这个实例对象存储了类中的所有成员变量
每个实例对象中都包含isa指针,这个指针指向该类的类对象
谈谈感悟:其实我们可以类比一下结构体
一.定义
1、 struct student{
int age;
}
2、类对象 Person
二、使用
struct student goodStudent;
Person *person = [Person alloc]init];
2、类、类对象、实例对象、方法、属性在内存中的存储
类:存储在代码区
类对象、实例对象、属性 存储在堆区
代表方法的函数指针存储在类对象中,也就是堆区中
3、分析类和类对象分开以及类对象和实例对象分开的好处
类代码存储在代码区:如果方法跟着类对象或者实例对象那就会占用堆中的很大空间
类对象:类对象创建一个,实例对象就不会都存储函数指针,只要想用是根据isa指针找到对应的类对象
然后根据对应的SEL找到存储在代码区中类的对应方法的代码段执行
这样分开都会节省很多内存
4.实例对象中的isa指针指向自己的类对象,自己类对象的isa指针指向了内存中类代码 如下图所示,
执行方法时,是到类方法中的方法列表中寻找,KVO原来,isa指针指向谁就到那个类对象中找对应的方法
kvo证明 1 runtime可以动态添加类
2 动态绑定方法 改变isa