iOS APP 开发 OC 第七天, 对象在内存中的储存

tags: OC 30 day

1. 内存中的五大区域:

栈 储存局部变量。
堆 工程师手动申请的字节空间 malloc calloc realloc函数。
BSS段 储存未被初始化的全局变量,静态变量。
数据段(常量区) 储存已被初始化的全局,静态变量,常量数据。
代码段 储存代码。

2. 类加载

在创建对象时,肯定是要访问类的。声明一个类的指针变量也会访问类。

当程序运行期间,当某个类第一次被访问到的时候,会将这个类储存到内存中的代码段区域。这个过程叫做类加载。
只有类在第一次被访问时,才会做类加载。
一但类被加载到代码段以后,直到程序结束的时候才会被释放掉。

3. 对象在内存当中究竟是如何储存的?

假设下面这段写在函数之中

Person *p1 = [Person new];
Person *p1; 会在栈内存当中申请一块空间,在栈内存中声明一个Person类型的指针变量p1。p1是一个指针变量,那么只能储存地址。[Person new]; 真正在内存中创建对象的是这段代码。
new做的事情:
a. 在堆内存中申请一块合适大小的空间。
b. 在这个空间中根据类的模板创建对象。
类模板中定义了什么属性,就把这些属性一次声明在对象之中,对象中还有另外一个属性,就是isa是一个指针(指向代码段)。
c. 初始化对象的属性
如果属性的类型是基本数据类型,那么就服值为0。
如果属性的类型是C语言的指针类型,那么就服值为NULL。
如果属性的类型是OC的类指针类型,那么就赋值为nil。
d. 返回对象的地址

我们来验证看看

@interface Person : NSObject{    @public    NSString *_name;    int _age;}-(void)sayHi;@end@implementation Person-(void)sayHi{    NSLog(@"大家好,我叫%@,我今年%d岁",_name,_age);}@endint main(int argc, char * argv[]) {    Person *p1 = [Person new];    NSLog(@"p1 = %p",p1);    return  0;}

首先来执行这一段代码,

我们会发现 *p1 的确是一个地址
那么 p1的对象还有一个isa指针。

下一个断点来看看

我们发现p1对象里面确实有一个isa的指针,但是我们无法对他进行访问。

补充

对象当中只有属性没有方法,自己的类的属性外加一个isa指针指向代码段中的类。如何访问对象的属性:指针名->属性名; 根据指针,找到指针指向的对象,再找到对象中的属性来访问。如何调用方法:[指针名 方法名]; 先根据指针名找到对象,对象发现要调用方法,再根据对象的isa指针找到类。然后调用类里的方法。为什么不把方法储存在对象之中?因为每一个对象的方法的代码实现都是一模一样的,没有必要为每一个对象都保存一个方法,这样太浪费空间了。


不同的对象,指向的是同一个记忆体
6. 对象的属性默认值:如果我们创建一个对象,没有为对象的属性复职,那么这葛对象的属性是有值的。如果属性的类型是基本的数据类型,默认值是0,如果属性的类型是C语言的指针类型,那么就服值为NULL。如果属性的类型是OC的类指针类型,那么就赋值为nil。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章