oc的类的本质,以及类编译时在内存中开辟的空间详析

来源:互联网 发布:善领dsa2016电子眼数据 编辑:程序博客网 时间:2024/06/12 00:30

最近一直在了解关于oc的类的知识,之前了解到的类都是在一个很浅显的层面上;


生活中的类无处不在,名词即为类,举个例子,Person为一个类,然后Person里有好多的属性,例如:_name,_age;

面向对象是从类中衍生出来的思维,有了它,我们可以很方便的看到结果,只论结果,不论过程;


例如:下面是通过面向对象的思维,通过类的方法,调用Person类的行为;




对于Person*p=[Person new];我一开的理解只是知道[Person new]是在内存中开辟了一个空间,用来存储我们的属性列表,以及我们的方法列表,具体里面是怎么开辟的,我了解得并不多,然后昨天时间比较多,而且机会比较好,我就详细的研究了一下,最后恍然大悟,因此想写下这篇博客和大家共勉。


首先看类的本质:类的本质是一个结构体指针!


Class是类的类型,Class cp就是定义了一个类类型的变量cp,[p class]是对象p的方法调用,调用[p class]方法的作用是将类在内存中的数据保存起来,然后将数据赋值给 cp,如下图。




对Class进一步探索发现,类类型实际是一个指针。




Class实际只是struct objc_class* 的别名;




class实际就是上图中的结构体。


类编译时在内存中开辟的空间详析

为了方便阅读,我画了个图



首先:1.在调用Person* p=[Person new]时会先在全局区中开辟一个空间,用来保存Class的对象,即类的模板;

(特别注意:里面有个SEL的方法的类型,会指向在代码区里的方法的实现)

    2.然后在堆区里开辟空间,用来存储类模板里的属性列表,以及方法列表;最后有个isa用来指向在全局区里的Class的对象(类的模板);

    3.在栈区开辟了指针p这个局部变量,用来指向在堆区里的属性列表等等;

当我们通过对象调用方法的时候,会先将方法封装为SEL类型,然后通过各类指针指向我们的全局区,最后和全局区里的方法的SEL类型进行比对,比对成功,则进入代码区进行代码的实现,比对不成功则报错;

   注:以上步骤的排序不代表在内存里开辟空间的先后顺序;

补充:在我们调用self 和super方法时,会有调用父类还是自己本身类方法的选择,在全局区里方法的SEL类型里有自己的方法,还有继承而来的父类方法,当用self时,会告诉系统,此时在全局区里调用的是自己的方法,用super时则是调用父类的方法。




2 0
原创粉丝点击