iOS之MRC与ARC

MRC & ARC

内存管理模型

一. 需要进行内存管理的对象

  1. 任何继承了NSObject的对象需要进行内存管理
  2. 非对象类型(int、char、float、double、struct、enum等) 不需要进行内存管理

二. 内存结构

1. 堆

一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收,分配方式类似于链表,继承了NSObject的对象存储在中。

2. 栈

由操作系统自动分配释放,存放函数的参数值,局部变量的值等,分配方式类似于

3. 数据段(data区)
4. 代码段(text区)

三. OC内存管理模型

1. 自动垃圾收集(iOS运行环境不支持)
2. 手动引用计数(MRC)和自动释放池(AutoReleasePool)
3. 自动引用计数(ARC)

四. MRC & AutoReleasePool – 手动引用计数与自动释放池

1. 引用计数器

引用计数器是一个整数,即对象被引用的次数。系统根据对象的引用计数器判断何时应该回收它所占用的内存。每个OC对象都有自己的引用计数器,任何对象刚创建的时候,引用计数器为1。

2. 引用计数器的操作
  1. 每当创建引用到对象需要给对象发送一条retain消息,此时该对象引用计数器值**+1。**

  2. 每当不需要该对象时给对象发送一条release消息,此时该对象引用计数器值**-1**

  3. 给对象发送retainCount消息,可以获得当前对象引用计数器值。

  4. 当对象的引用计数器值为0时,系统通过给该对象发送dealloc消息,释放该对象的内存。

3. dealloc
  1. 对象即将被销毁时系统会自动给对象发送一条dealloc消息。
  2. 一般会重写dealloc方法,即在这里释放相关资源,该方法一旦重写,必须在方法最后调用**[super dealloc]**。
  3. 不能直接调用dealloc方法。
4. 野指针和空指针
  1. 当一个指针指向一个“僵尸对象”(被释放了的对象),这个指针就是野指针
  2. 为避免给野指针发送消息报错,在它指向的对象被释放后,将它设置为空指针(没有指向存储空间的指针)。
5. 自动释放池 – AutoReleasePool
  1. autorelease是一种支持引用计数的内存管理方式,给对象发送一条autorelease信息,会将对象放到一个自动释放池中,当自动释放池被销毁时,会对池子中的所有对象发送一次release消息(只是发送release消息,并不是将对象直接释放)。

  2. autorelease方法会返回对象本身,其实质上是延迟了给对象发送release消息的操作。

  3. NSAutoreleasePool *pool创建等同与@autoreleasepool创建,前者需要调用 [pool drain]来销毁自动释放池。

  4. 自动释放池中不适宜放占用内存较大的对象或大量循环操作。

6. 循环retain
  1. 当A对象要拥有B对象,同时B对象要拥有A对象,此时会形成循环retain,导致A和B对象永远无法释放。

  2. 尽量避免双端互相引用,或者一端用retain,一端用assign。

五. ARC – 自动引用计数

1. ARC

自动引用计数,系统检测出何时需要保持对象,何时需要自动释放对象,编译器会管理内存,并在合适的地方加入retainreleaseautorelease

2. ARC的判断原则 – 强指针
  1. ARC通过强指针判断一个对象是否需要释放。

  2. 默认所有对象的指针变量都是强指针,或者被“__strong”修饰的指针。

  3. 被**__weak修饰的指针是弱指针**。

  4. 只要还有一个强指针变量指向对象,对象就会保持在内存中。

3. ARC的注意事项
  1. 不能调用对象的release方法。
  2. 不能调用autorelease方法。
  3. 重写dealloc方法时,不能调用**[super dealloc]**。
4. 单对象内存管理
  1. 局部变量(局部强指针)超出作用域释放,对象随之被释放。

  2. 清空指针(默认清空的所有指针都是强指针),对象随之被释放。

  3. 弱指针保存新创建的对象时,对象会立即被释放。

5. 多对象内存管理
  1. 想要拥有某个对象必须使用强指针保存它,无需在dealloc方法中release。
6. property参数
  1. strong:用于OC对象,相当于MRC中的retain。
  2. weak:用于OC对象,相当于MRC中的assign。
  3. assign:用于基本数据类型,与MRC中的assign相同。
7. 循环引用

如果A拥有B,B也拥有A,那么其中一方必须使用弱指针。

Comments