应用程序的内存管理:是一个过程,程序在运行时分配内存,使用内存,当程序结束时释放内存。一个编写有着良好编程习惯的的程序员应该尽可能少的占用内存。在OC中,它也可以被视为一种给数据和代码分配有限的内存资源的所有权。
在我们iOS开发过程中,内存分为5大区:堆区,栈区,全局静态区,常量区和代码区,而可以供我们自行管理内存的区域只有堆区(即存在堆区的对象).现在一个iPhone手机的内存只有1G,可以提供给一个程序使用的内存只有50M左右,超过50M就会发生闪退现象,影响手机性能.所以只有一个占用内存少的程序才能拥有更长的生命周期.所以内存管理极其重要.
现在开发过程中,提供了两种内存管理机制MRC(Manual ReferenceCounting)和ARC(Automatic Reference Counting),分别提供对内存的手动和自动管理,来满足不同的需求。ARC是iOS 5推出的新功能,简单地说,就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。ARC的本质还是MRC,他们都是使用引用计数的方式对内存进行管理.ARC只是在MRC的基础上,系统自动帮你增加或者减少引用计数.
在内存管理中,最重要的原则就是引用计数加减平衡,即引用计数每增加一次,不在使用时就减去一次.
如果最后引用计数大于0 则会内存泄露
如果引用 计数等于0还对该对象进行操作,则会出现内存访问失败,crash.所以尽量设置为nil
会引起引用计数改变的方法:
+alloc 开辟一块内存引用计数为1的对象(类方法)
-dealloc 在所有对象的引用计数从1变为0时,系统会自动调用此方法将对象销毁
-retain 对象的引用计数+1(对象方法)
-release 与retain对应,对象引用计数-1 (对象方法)
-copy copy 一个对象变成新的对象(新内存地址) 引用计数为1 原来对象计数不变(对象方法)
autorelease 对象引用计数不会立即 -1 在最近一个pool释放时,会遍历整个自动释放池,对其中所有对象引用计数-1
1.alloc与retain的使用
如图,在alloc之后,引用计数变为一,进行一次retain之后,引用计数 +1
2.release的使用
如图,对应retain,要进行引用计数-2,然后系统会调用dealloc,将对象销毁.
3.过度释放的产生
如图,之前引用计数为2,release3次之后,系统就会奔溃,这个属于过度释放
4.copy的使用
如图,copy使用时不会使原有对象的引用计数改变,只改变产生的新对象的引用计数
5.autorelease的使用
如图,在autorelease之后,引用计数不会立即减一,而出了释放池之后,对象会立即被销毁
6.容器的内存管理
1.当对象被加入容器中时,引用计数会 +1
2.当对象被从容器中移除时,引用计数 -1.
最后对内存管理总结一下:
1.谁创建,谁释放(类似于“谁污染,谁治理”)。如果你通过alloc、new或copy来创建一个对象,那么你必须调用release或autorelease。换句话说,不是你创建的,就不用你去释放。
例如,你在一个函数中alloc生成了一个对象,且这个对象只在这个函数中被使用,那么你必须在这个函数中调用release或autorelease。如果你在一个class的某个方法中alloc一个成员对象,且没有调用autorelease,那么你需要在这个类的dealloc方法中调用release;如果调用了autorelease,那么在dealloc方法中什么都不需要做。
2.除了alloc、new或copy之外的方法创建的对象都被声明了autorelease。
3.谁retain,谁release。只要你调用了retain,无论这个对象是如何生成的,你都要调用release。