IOS内存管理

IOS内存管理

背景:IOS中,内存主要被“划分”为4大块区被利用,分别为:栈、堆、全局去、常量区

1.栈区:由编译器自动分配释放

2.堆:由开发者分配释放,若不释放,程序结束时由系统回收

3.全局区:又称静态区,全局变量和静态变量的存储是放在一起的,他们中初始化的放在一起,没有初始化的放在另一个区

4.常量区:专门存放常量的地方,程序结束时释放。

开发中,我们一般要管理下堆的内存,具体到我的应用中,一般基本变量的内存管理我们不用操心,因为基本变量的是放在栈区的,由编译器自动帮我们处理内存,我们要管理的是对象,对象放在堆区。

我们知道Java中有垃圾回收机制可以帮开发者管理内存,objective-c语言本身也是有垃圾回收机制的,但是IOS系统不支持垃圾回收机制,那么objective-c语言使用哪些方法来达到内存管理的目的呢?

在IOS中,与管理内存有关的概念有以下:

1.引用计数(分手动引用、自动引用)

当创建一个对象时(alloc/new/copy/mutableCopy)引用变量就会获取到该对象的所有权,此时该对象的引用计数(RC)为1

如何让另一个引用也获取该创建对象的所有权呢?我们可以使用retain来使得其它变量获取对象所有权

如何让另一个引用放弃已经获取的所有权呢?可以通过使用release来实现

上面只是对引用对边进行对象拥有权限的操作,那如何释放一个对象呢?可以使用dealloc,值得注意的是,在开发中,我们不需要人为地去调用该方法,因为每一个对象只要它的RC=0时,系统就会自动调用dealloc方法来释放该对象。

手动引用(MRC)ios5以前使用,它需要开发者手动管理引用计数的增减(retain/release);

自动引用(ARC)则是由编译器自动帮开发者加入retain/release的代码,从而实现增减引用计数的目的,其本质还是对引用计数进行操作,不过是编译器帮开发者做了增减那些操作而已。

对于ARC来说,编译器使用__strong、__week、__unsafe_unretained、__autoreleasing等修饰符来实现对引用计数的管理,比如:如果你在ARC环境下创建一个对象(默认编译器会使用__strong来修饰),当获取一个对象拥有权或者释放一个对象拥有权时,不用我们人为去调用release、retain来实现。除了当__strong变量超过作用域时,编译器会自动加入release语句来释放内存,如果将__strong变量赋值给其它变量的话,ARC也会自动帮我们使用release变量来释放它之前指向的对象。反过来,如果变量var被__strong修饰,当变量var指向某个对象objc,那么变量var将拥有objc所有权。

编译器根据__strong修饰符来管理对象内存,但是__strong并不能解决引用循环问题,这样就会造成内存不能释放,引起内存泄露问题。这个时候,出现了__weak修饰符,它修饰的引用并不会拥有所指对象的所有权,当超出它的返回时,它会自动将引用设置为nil.

__unsafe_unretained 修饰符与__weak是一样的作用,不同的时,当超出它的范围时,它不会被设置为nil,导致出现野指针.

xcode引入property modifier属性后,所使用的修饰符其实也是基于上面的strong、__week、__unsafe_unretained、__autoreleasing, 如property中就有对应__strong的strong、retain、copy

也有weak对应__weak,assign对应__unsafe_unretained, unsafe_unretained对应__unsafe_unretained

2.自动释放池Autorelease Pool

自动释放池可以看做一个存储代码块的容器,只要超出这个容器,那么容器就会对其中的对象发起release操作,这样对象就能实现引用计数减少的操作了,其本质还是使用了引用计数器来实现对内存的管理,特别的是它是能让对象在一定空间和时间内继续存在,当超出这个时空,就会自动批量帮我们释放对象,比起手动释放要轻松许多。

值得注意的是,使用自动释放池来管理内存,要保证在一定时空内不要让内存长期增长,因为在这一定的时空内,由于自动释放池的延迟性,对象暂时不会释放,所有也有可能导致内存泄露引起崩溃。

综上所述:

要想掌握iOS/OS X的内存管理,首先要深入理解引用计数(Reference Count)这个概念以及内存管理的规则;在没引入ARC之前,我们都是通过retain和release方法来手动管理内存,但引入ARC之后,我们可以借助编译器来帮忙自动调用retain和release方法来简化内存管理和减低出错的可能性。虽然__strong修饰符能够执行大多数内存管理,但它不能解决引用循环(Reference Cycle)问题,于是又引入另一个修饰符__weak。被__strong修饰的变量都持有对象的所有权,而被__weak修饰的变量并不持有对象所有权。

注:有参考网络资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值