原文:http://blog.csdn.net/fanyiyao980404514/article/details/44864663
在C++的内存模型中我们知道,我们通过虚函数列表来存储虚函数的虚拟内存地址,再数据块中加入一个指向虚函数列表的指针变量,通过指针变量来得到虚函数列表,再通过虚函数列表来调用虚函数来实现多态的面向对象的编程功能。
既然OC是面向对象的高级计算机语言。它有一个语言运行时,我们可以动态的判断改实例变量是否拥有该函数。通过运行时来创建对应类的变量,通过运行时来添加成员变量和成员函数,通过运行时来复制实例变量。
开一下内存模型的运行状态图(来源网络)
isa指针变量就是is a .....这个指针变量指向的就是该变量的类信息,所有的类都是继承至NSObject基类。
instance of subclass:堆内存块存储的是用户设计时的成员变量和编译器给你添加的一些成员变量,添加的这些成员变量是用来支持运行时的。instance of subclass指向的它的类对象subclass object。
subclass是类对象,该对象中的信息是该类的成员函数的指针地址列表,它有指向该类的元类对象subclass(meta)。
元类对象subclass(meta)这也是系统创建的用来支持语言运行时,该类的中存储的是该子类的类函数的指针地址列表,通过改列表来调用该类的类函数。
子类的最终指向都是NSObject的类对象和和元类对象,类对象指向父类的类对象,元类对象指向父类的元类对象,NSObject的类对象指向nil,这就能说明nil掉用任何方法都不会抱错的原因了。
下面我们来声明一个OC的类,这个类中有成员变量和成员函数和类函数,之后来看它的运行时内存状态。
头文件:
- #import <Foundation/Foundation.h>
- @interface SubclassTest : NSObject
- //成员变量的声明
- @property (nonatomic,retain)NSString *attrOne;
- @property (nonatomic,retain)NSString *attrTwo;
- @property (nonatomic,retain)NSString *attrThree;
- //成员函数的声明
- -(void)instanceMethodOne;
- -(void)instanceMethodTwo;
- -(void)instanceMethodThree;
- //类函数的声明
- +(void)classMethodOne;
- +(void)classMethodTwo;
- +(void)classMethodThree;
- @end
运行状态图:
当我们使用这样的一个句子SubclassTest *obj = [[SubclassTest alloc]init];内存状态如下:
小结 :
其中我们编程要关心的时SubclassTest的实例,其他的类对象和元类对象是语言运行时的支持对象。
我们在成员方法中使用的self是实例对象。
我们在类方法中使用的self是类对象,要注意区别它们的关系。
同的来说,OC最终也要编译成计算机CPU指令可以把它映射为数据块的参数传递,和服务函数的调用,至于函数的调用通过函数指针来实现,函数指针的如何调用如何存储如何组织,通过包装之后写成规范并实现其编译器,也就成为另一门新的计算机语言了。汇编通过包装称为C++,C++通过封装加运行时称为了OC,java,C#等计算机高级编译型语言,随着计算机的发展为来语言又会变成什么样了,如果编译器越来越智能,它能够通过我们的自然语言就能自动实现计算机CPU指令的生成,到哪个时候还要程序猿干嘛。。。。