<link rel="stylesheet" href="http://yandex.st/highlightjs/6.2/styles/googlecode.min.css">
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://yandex.st/highlightjs/6.2/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script type="text/javascript">
$(document).ready(function(){
$("h1,h2,h3,h4,h5,h6").each(function(i,item){
var tag = $(item).get(0).localName;
$(item).attr("id","wow"+i);
$("#category").append(‘<a class="new‘+tag+‘" href="#wow‘+i+‘">‘+$(this).text()+‘</a></br>‘);
$(".newh1").css("margin-left",0);
$(".newh2").css("margin-left",20);
$(".newh3").css("margin-left",40);
$(".newh4").css("margin-left",60);
$(".newh5").css("margin-left",80);
$(".newh6").css("margin-left",100);
});
});
</script>
<div id="category"></div>
# 内存管理大总结
## 1.自动引用计数的概念
- 在OC中采用引用**计数机制**来管理对象的生命周期.
- 在实际的项目中,我们在函数内使用一个临时的对象,通常是不需要修改它的引用计数的,只需要在函数返回前将该对象销毁即可.
- 引用计数真正排上用场是,对象之间传递和共享数据.遵从引用计数这个规则的话,对象的生命周期的管理就完全可以交给引用计数了.
## 2.内存管理/引用计数
### 2.1.1 内存管理的思考方式
举例 对办公室照明设备所做的动作和对OC对象所做的动作
对照明设备所做的动作|对OC对象所做的动作|OC方法
------|---|---
开灯|生成并持有对象|alloc/copy/new/mutableCopy等方法
需要照明|持有对象|retain方法
不需要照明|释放对象|release方法
关灯|废弃对象|dealloc方法
小结:
- 自己生成的对象,自己持有
- 非自己生成的对象.自己也可以持有
- 不再需要自己持有的对象时释放
- 非自己持有的对象无法释放
这些有关的OC内存管理的方法,实际上不包括在该语言中,而是包含在Cocoa框架中用于OSX iOS应用开发.Cocoa框架中的Foundation框架类库中的NSObject类担负内存管理的职责.OC内存管理中的alloc/retain/release/dealloc方法分别指代NSObject类的alloc类方法,retain实例方法,release实例方法和dealloc实例方法.
- 自己生成对象并持有.举例:
`NSArray *arr1 = [[NSArray alloc]init]; //取得对象,并持有;`
- 非自己生成的对象,即使用alloc/copy/new/mutableCopy以外的方法取得的对象,也可以持有.举例:
`NSArray *arr2 = [NSArray array];//取得对象,但并不持有;`
`[arr2 retain];//自己持有对象`
- 不再需要自己持有的对象时释放.举例`[arr1/arr2 release];`特殊的是 针对arr1,自己生成并持有的对象,可以采用 `[arr1 autorelease];`,因为autorelease提供这样的功能,使对象在超出指定的生存范围时能够自动并正确的释放(调用release方法).
- 无法释放非自己持有的对象:如果对象的引用计数已经为0,则不能再次释放,非自己持有的对象更不能释放.
release和autorelease的区别
release|autorelease
--|--
对象立即释放|对象不立即释放,注册到autoreleasepool中,pool结束时自动调用release
### 2.1.2 alloc/retain/release/dealloc实现
- 在OC的对象中存有引用计数这一整数值(retainCount)
- 调用alloc/new/copy/mutableCopy/retain方法后,引用计数值+1.
- 调用release后,引用计数-1.
- 引用计数为0时,调用dealloc方法废弃对象
### 2.1.5 autorelease
`autorelease`的具体使用方法如下:
- 生成并持有`NSAutoreleasePool`对象;
- 调用已分配对象的`autorelease`实例方法;
- 废弃`NSAutoreleasePool`对象.
```
NSAutoreleasePool *pool = [][NSAutoreleasePool alloc]init];
id obj = [[NSObect alloc]init];
[obj autorelease];
[pool drain];
```
尽管如此,当在大量产生autorelease对象时,只要不废弃NSAutoreleasePool对象,那么生成的对象就不能被释放,因此有时候会产生内存不足的现象.正确的做法是 把自动释放池的创建放在for循环内.代码如下:
```
for(int i = 0; i< 100000;i++)
{
NSAutoreleasePool *pool = [][NSAutoreleasePool alloc]init];
//读入图像,产生大量`autorelease`的对象.
[pool drain];
}
```
**在OC中,也就是Foundation框架时,无论调用哪一个对象的`autorelease`实例方法,实际上调用的都是NSObject类的`autorelease`实例方法.但是对于`NSAutoreleasePool`类,`autorelease`实例方法已被该类重载,因此运行就会报错.**
```
//这样写是错误滴
NSAutoreleasePool *pool = [][NSAutoreleasePool alloc]init];
[pool autorelease];
```