内存管理
程序运行的过程中往往会涉及到创建对象、定义变量、调用函数或方法,而这些行为都会增加程序的内存占用。为了防止内存占用过多影响到程序的正常运行就需要对内存进行管理。
移动端的内存管理机制,主要有三种:
- 自动垃圾收集(GC)
- 手工引用计数和自动释放池(MRC)
- 自动引用计数(ARC)
苹果公司使用的是手工引用计数(MRC)和自动引用计数(ARC)机制。
内存分区
iOS中内存分为五大区域:
-
代码区:存放程序运行的机器指令,只读。
-
常量区:常量区用于存储常量数据,如字符串字面量和常量数值(int、float、string等)。这些数据在整个程序运行期间不能被修改,通常在编译时就确定了。常量区的数据在程序结束时由系统释放。
-
全局区/静态区:它主要存放静态数据、全局数据和常量。分为未初始化全局区(BSS 段)、初始化全局区:(data段)。这些变量在程序整个生命周期内都存在,除非程序终止。全局区和静态区在程序启动时由系统分配,并在程序结束时由系统释放。一般以
0x1
开头 -
栈区:存放局部变量、函数参数和函数调用的返回地址等。由编译器自动分配和管理的一块从高地址向低地址存储的一块连续的内存区域。栈空间分静态分配和动态分配两种:静态分配是编译器完成的,比如自动变量(auto)的分配。动态分配由alloc函数完成。栈的地址空间在在iOS里面是
0X7/ 0X16
开头 -
堆区:用于存放进程运行中被动态分配的内存段。它大小不固定,可动态扩张和缩减。从低地址向高地址的不连续的内存区域。由程序员分配和释放。堆地址是以
0X6
进行开头
对象的指针通常存储在栈中,对象本身存储在堆中
static、extern、const
静态变量通过static关键字修饰,分为全局静态变量和局部静态变量。唯一区别就是作用域不同。
static NSString *name;
不管实例方法还是类方法都可以访问和修改静态变量,并且外部类无法调用静态变量,定义后只会指向固定的指针地址,供所有对象使用,节省空间。
全局变量分为对内和对外两种。
//.m中要定义
NSString *name;
//.h中同时要定义
extern NSString *name;
-
对内的全局变量:没有用extern在.h中修饰的变量,仅定义在.m中让该变量只能在该类使用
-
外部全局变量:除了该类,其他文件也可以访问该变量
全局静态变量与全局变量 其实本质上是没有区别的,只是存在修饰区别,一个static让其只能内部使用,一个extern让其可以外部使用。
const修饰常量,常量为只读不可修改,一般用于接口或者文字显示这种固定值
//.h中定义extern
extern NSString *const name;
//.m中定义值
NSString *const name = @"123";