[iOS] 内存管理[一]

引用计数

面试问答:

问题:
    Oc对象什么时候会被释放?/对象占用的内存什么时候会被回收?
答:
    当对象没有被任何变量引用(也可以说是没有指针指向该对象)的时候,就会被释放。

ObjC采用引用计数(reference counting)的技术来进行管理:

  • 1)每个对象都有一个关联的整数,称为引用计数器
  • 2)当代码需要使用该对象时,则将对象的引用计数加1
  • 3)当代码结束使用该对象时,则将对象的引用计数减1
  • 4)当引用计数的值变为0时,表示对象没有被任何代码使用,此时对象将被释放。

方法如下:

  • 1)当对象被创建(通过alloc、new或copy等方法)时,其引用计数初始值为1
  • 2)給对象发送retain消息,其引用计数加1
  • 3)給对象发送release消息,其引用计数减1
  • 4)当对象引用计数归0时,ObjC給对象发送dealloc消息销毁对象

自动释放池

自动释放池创建后,就会成为活动的池子,释放池子后,池子将释放其所包含的所有对象。

自动释放池什么时候创建?

  app使用过程中,会定期自动生成和销毁自动释放池,一般是在程序事件处理之前创建,当然我们也可以自行创建自动释放池,来达到我们一些特定的目的。

自动释放池什么时候销毁?

  自动释放池的销毁时间是确定的,一般是在程序事件处理之后释放,或者由我们自己手动释放

使用自动释放池需要注意:

  • 1)自动释放池实质上只是在释放的时候給池中所有对象对象发送release消息,不保证对象一定会销毁,如果自动释放池向对象发送release消息后对象的引用计数仍大于1,对象就无法销毁。
  • 2)自动释放池中的对象会集中同一时间释放,如果操作需要生成的对象较多占用内存空间大,可以使用多个释放池来进行优化。比如在一个循环中需要创建大量的临时变量,可以创建内部的池子来降低内存占用峰值。
  • 3)autorelease不会改变对象的引用计数

iOS的内存管理规则

基本原则

  无规矩不成方圆,在iOS开发中也存在规则来约束开发者进行内存管理,总的来讲有三点:

  • 1)当你通过new、alloc或copy方法创建一个对象时,它的引用计数为1,当不再使用该对象时,应该向对象发送release或者autorelease消息释放对象。
  • 2)当你通过其他方法获得一个对象时,如果对象引用计数为1且被设置为autorelease,则不需要执行任何释放对象的操作;
  • 3)如果你打算取得对象所有权,就需要保留对象并在操作完成之后释放,且必须保证retain和release的次数对等。

ARC

   在MRC时代,必须严格遵守以上规则,否则内存问题将成为恶魔一样的存在,然而来到ARC时代,事情似乎变得轻松了,不用再写无止尽的ratain和release似乎让开发变得轻松了,对初学者变得更友好。

  ObjC2.0引入了垃圾回收机制,然而由于垃圾回收机制会对移动设备产生某些不好的影响(例如由于垃圾清理造成的卡顿),iOS并不支持这个机制,苹果的解决方案就是ARC(自动引用计数)。

  iOS5以后,我们可以开启ARC模式,ARC可以理解成一位管家,这个管家会帮我们向对象发送retain和release语句,不再需要我们手动添加了,我们可以更舒心地创建或引用对象,简化内存管理步骤,节省大量的开发时间。

实际上,ARC不是垃圾回收,也并不是不需要内存管理了,它是隐式的内存管理,编译器在编译的时候会在代码插入合适的ratain和release语句,相当于在背后帮我们完成了内存管理的工作。