[Objective-C]内存管理

假定有两个Person的实例,每个都有一个指针成员变量favoriteColor,指向一个颜色对象。假如两个人喜欢同样的颜色,这两个实例就会指向同一个颜色对象。随着年纪的变化,每个人喜欢的颜色可能会发生改变,最后,原来的颜色对象可能就没有人使用了。如图1-1

这里写图片描述
图1-1

谁都不希望这个“孤儿”颜色继续留在程序中占用内存空间,而是希望对内存重新分配,能将新的对象放到那个存储区域。但是,开发者需要确保释放的颜色对象已经没有人再使用了。

对此,Apple使用了三种方法来解决:

  • 采用手动引用计数,即retain计数:每个对象都有一个retain计数,表示指向它的其他对象的个数。假如某个颜色时两个人都喜欢的颜色,那么retain计数就是2。当retain计数变为0时,该对象就被释放。
  • 在Mac OS 10.5系统中,针对Objective-C引入了垃圾回收机制(GC)。垃圾回收机制监视整个对象关系图,查找那些在作用域内已经没有任何对象指向的对象,将自动释放这些对象。
  • 最新的解决方案是,在Mac OS 10.7和iOS 5中引入自动引用计数(自动内存管理机制,ARC),ARC依靠最初的retain计数机制,但有些不同,即编译器管理程序的retain计数管理档案。(目前在XCODE中的工程模板中是默认使用ARC)

其实,ARC是某种程度上的折中,因为手动引用计数需要手动进行,增加工作量,开发者需要显式保存对象的访问,还需要在对象不再使用时显式的进行释放。假如不小心使用,retain计数机制将产生麻烦的后果:对象A retain对象B,而B又retain A ,这样就产生了永远删不掉的内存孤岛,因为它们还互相retain着的。这就是retain循环。图1-2即retain循环的例子:

这里写图片描述
图1-2

而垃圾回收机制看似很合理,但却产生性能消耗:它需要占用CPU时间来扫描对象,查找垃圾。这有时会让应用程序产生很差的或者不稳定的性能表现。例如:在一个需要稳定表现得应用程序里面(如一个动作游戏)或者需要实时进行渲染并回放的视频播放,垃圾回收机制可能因扫描引起程序短暂的停顿。此外,垃圾回收机制还不能管理手动分配的内存(例如使用malloc()函数,没有特别的方法)。垃圾回收机制不能运行在Mac OS 10.5以前的版本上,也不能移植到iOS上,这些都不支持垃圾回收机制。

ARC(Automatic Reference Counting)提供一个很好的解决方案——既获得了手动引用管理的速度和效率,也享有使用垃圾回收机制带来的便利。但是ARC并不完美,它不能解决retain循环的问题,像垃圾回收机制一样,不能管理手动分配的内存。

手动内存管理
retain计数是一个相当简单的概念,Objective-C中的每一个对象都有一个retain计数。retain计数是一个整数。使用alloc函数创建一个对象时,该对象的retain计数设为1。当retain计数变为0时,对象就被释放。一般通过发送retain消息给对象,从而增加对象的retain计数;发送release给对象,则减少retain计数的值。

一个对象的retain计数表示该对象被多少个其他的对象引用,当retain计数变为0时,表明已经没有其他对象关心这个对象了,就要被释放掉,腾出内存空间。

Retain计数机制可以让程序员很方便的控制对象怎么释放以及何时释放,但需要非常小心。如果一个对象被多次释放,那么这个对象很有可能被提前释放,程序就会崩溃:如果多次retain一个对象,那么这个对象将永远不会被释放,就会浪费内存。

手动管理主要三种方式:retain、release和autorelease。

使用ARC
ARC是编译器的一个功能,与支持代码静态分析机制一样。当开发者编译应用程序时,编译器将检查Objective-C对象指针(也叫引用)的用法,然后应用retain规则,进行retain计数、释放和自动释放的检查,确保对象在需要时能够正确存在,在不需要时被重新分配。

强引用
默认情况下的引用都是强引用,假如一个对象被分配为强引用,ARC则认为该对象就在附近,并且retain也是隐式的。假如将引用改变为一个新的值,旧的对象被释放,新的对象被retain。

弱引用
弱引用与旧的手动引用计数类似:没有隐式的retain,指针值只在内存中修改。然而这样的引用一直是引起程序崩溃的原因。假如指针没有被retain,这个对象就被重新分配,那么将留下一个坏指针,在以后使用时就是一个潜在的引起崩溃的原因。ARC解决这个问题的方法是指针指向的对象被重新分配时,自动将弱引用设为nil,这就是所谓的“Zeroing weak reference”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值