app开发

OC的中对象的存储,方法调用的原理(个人理解)

2016-07-13  本文已影响335人  星空眼泪tingdong

1.我们的都知道内存中一般分成这几块区域

A  静态数据区:内存在程序启动的时候才被分配,而且可能直到程序开始执行的时候才被初始化,如函数中的静态变量就是在程序第一次执行到定义该变量的代码时才被初始化。所分配的内存在程序的整个运行期间都存在,如全局变量,static变量等。

注意:初始化的全局变量和静态变量在一块区域,未初始化的全局变量与静态变量在相邻的另一块区域,同时未被初始化的对象存储区可以通过void*来访问和操纵,程序结束后由系统自行释放。

B  代码区:存放函数体的二进制代码;

C  栈区:存放自动变量。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元由编译器自动释放,超出其作用域外的操作没有定义。栈内存分配运算内置于处理器的指令集中,效率很高,但分配的内存容量有限。栈存放函数的参数值,局部变量的值等。

D  堆区(自由存储区):在运行的时候调用程序(如C中的malloc或C++中的new)分配内存,可以在任何时候决定分配内存及分配的大小,用户自己负责在何时释放内存(如用free或delete)。堆中的所有东西都是匿名的,这样不能按名字访问,而只能通过指针访问。(只有这个区域,需要我们手动管理的内存)。

E  常量区: 存储的都是一些字符串常量,有系统自行分配和回收。

2.类创建对象,每个对象在内存中都占据一定的存储空间(存放在堆区中),每个对象都有一份属于自己的单独的成员变量(所以所有的成员变量每个对象都会从类对象中复制一份到自己的存储空空间中去,但是不复制类对象的方法),所有的类对象方法在整个内存中只有一份,类对象本身在内存中也占据一份存储空间,类对象的方法存储于此(因为方法的本质就是具有功能的一个函数体,所以应该是存在代码区)。

那么为了解决,所有的对象的都可以访问到类对象的方法和公共的成员变量:每一个对象都包含一个isa指针(isa是对象中的隐藏指针).这个指针指向当前对象所属的类。[car run];表示给car所指向的对象发送一条eat消息,调用对象的run方法,此时对象会顺着内部的isa指针找到存储于类中的方法,执行。

在OC中存在一个名为id的类型,这个和上面所说这个isa指针有一定的联系.C代码

typedef struct objc_object {Class isa;

} *id;

其中Class类型为指向objc_class结构体的指针类型.

这些对象在内存中都是由其地址唯一标示,所有的对象都是id类型的.

3、使用一个类创建多个对象

Car *car = [Car new];

Car *car1 = [Car new]

当使用一个类创建多个对象的时候,注意:

1)不同的对象在内存中分配的是不同的存储地址,所以各成员属性的地址也各不相同

car和car1的isa指针都指向了Car类,当调用[car run]方法的时候,就会顺着isa指针找到类对象中的run的方法。

4.继承时候的的对象存储

当我们一个A类继承另一个B类的时候,由A创建出来的A对象,都会有一个B类的创建的B对象。所以就等于我们A就拥有了B所有的成员的变量和类对象的方法(不考虑关键字@private的使用情况)。

上一篇下一篇

猜你喜欢

热点阅读