首先我们先简单了解(复习)一下栈与堆
1、栈区:存放函数的参数值、局部变量等,由编译器自动分配和释放,通常在函数执行完后就释放了,其操作方式类似于数据结构中的栈。栈内存分配运算内置于CPU的指令集,效率很高,但是分配的内存量有限,比如iOS中栈区的大小是2M。
2、堆区:就是通过new、malloc、realloc分配的内存块,编译器不会负责它们的释放工作,需要用程序区释放。分配方式类似于数据结构中的链表。在iOS开发中所说的“内存泄漏”说的就是堆区的内存。
3、静态区:全局变量和静态变量(在iOS中就是用static修饰的局部变量或者是全局全局变量)的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后,由系统释放。
4、常量区:常量存储在这里,不允许修改。
5、代码区:存放函数体的二进制代码。
这样看起来似乎有些难理解,接下里我简单描述一下
值类型存储数据方式:通常在全局作用域里申明一个值类型变量,此时会在栈中开辟一个空间,存储变量的值
下面简单的用代码形式展现一下
首先申明变量a,值为1,在栈中存储的是1,接着再申明变量b,将a值赋值给它,这里相当于是复制了一份a的值给b,这样修改b的值,a值当然不会发生改变啦,这就是值类型。
引用类型存储数据方式:我们同样在全局作用域里申明一个引用类型数组arr,此时会在内存堆中开辟一个空间,有个地址值0x123,空间里面存储的就是数组arr的值,而栈中存储的是空间的地址值0x123,
那么此时,我们将数组重复赋值给一个新变量arr2,然后对新变量arr2的数组值进行修改,此时arr原本的数据也会发生改变!
首先申明一个数组arr = [1,2,3],此时在内存开辟堆空间地址值为0x123,存储的是[1,2,3],栈中存储的是地址值0x123,再申明数组arr2,将arr的地址值赋值给它,此时修改arr2下标为0的数据,是会对arr数据有影响的,因为两个数组栈中存储的地址值相同,都是指向同一个空间0x123
1.值类型
值类型存储到栈中,值存入栈内,拷贝变量值,再复制给新变量,这时候改变新变量的值,原变量值不会变
2.引用类型
值存储到堆中,栈中存储的是地址值,将值存入堆内,再产生一个地址值,存入栈内,如果需要复制给新变量,是将地址值赋值给新变量,这时候改变新变量的值,会影响原先的变量,因为地址值相同,指向同一个堆
大致内存图如下: