从 c++ 到 objective-c(14):内存管理(续)

从 c++ 到 objective-c(14):内存管理(续)

ID:6299403

大小:47.00 KB

页数:4页

时间:2018-01-09

从 c++ 到 objective-c(14):内存管理(续)_第1页
从 c++ 到 objective-c(14):内存管理(续)_第2页
从 c++ 到 objective-c(14):内存管理(续)_第3页
从 c++ 到 objective-c(14):内存管理(续)_第4页
资源描述:

《从 c++ 到 objective-c(14):内存管理(续)》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、从C++到Objective-C(14):内存管理(续)作者: DevBean 日期:2011年03月30日发表评论 (5)查看评论autorelease池上一节中我们了解到autorelease的种种神奇之处:它能够在合适的时候自动释放分配的内存。但是如何才能让便以其之道什么时候合适呢?这种情况下,垃圾收集器是最好的选择。下面我们将着重讲解垃圾收集器的工作原理。不过,为了了解垃圾收集器,就不得不深入了解autorelease的机制。所以我们要从这里开始。当对象收到autorelease消息的时候,它会被注册到一个“autorelease池”。当这个池被销毁时,

2、其中的对象也就被实际的销毁。所以,现在的问题是,这个池如何管理?答案是丰富多彩的:如果你使用Cocoa开发GUI界面,基本不需要做什么事情;否则的话,你应该自己创建和销毁这个池。拥有图形界面的应用程序都有一个事件循环。这个循环将等待用户动作,使应用程序响应动作,然后继续等待下一个动作。当你使用Cocoa创建GUI程序时,这个autorelease池在事件循环的一次循环开始时被自动创建,然后在循环结束时自动销毁。这是合乎逻辑的:一般的,一个用户动作都会触发一系列任务,临时变量的创建和销毁一般不会影响到下一个事件。如果必须要有可持久化的数据,那么你就要手动地使用re

3、tain消息。另一方面,如果没有GUI,你必须自己建立autorelease池。当对象收到autorelease消息时,它能够找到最近的autorelease池。当池可以被清空时,你可以对这个池使用release消息。一般的,命令行界面的Cocoa程序都会有如下的代码:intmain(intargc,char*argv[]){NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];//...[poolrelease];return0;}注意在MacOSX10.5的NSAutoreleasePool类新增加了一个

4、drain方法。这个方法等价于:当垃圾收集器可用时做release操作;否则则触发运行垃圾收集。这对编写在两种情况下都适用的代码时是很有用的。注意,这里实际上是说,现在有两种环境:引用计数和垃圾回收。MacOS的新版本都会支持垃圾收集器,但是iOS却不支持。在引用计数环境下,NSAutoreleasePool的release方法会给池中的所有对象发送release消息,如果对象注册了多次,就会多次给它发release。drain和release在应用计数环境下是等价的。在垃圾收集的环境下,release不做任何事情,drain则会触发垃圾收集。使用多个autor

5、elease池在一个程序中使用多个autorelease池也是可以的。对象收到autorelease消息时会注册到最近的池。因此,如果一个函数需要创建并使用很大数量临时对象,为了提高性能,可以创建一个局部的autorelease池。这种情况下,这些临时变量就可以及时的被销毁,从而在函数返回时就将内存释放出来。autorelease的注意点使用autorelease可能会有一些误用情况,需要我们特别注意。·首先,非必要地发送多个autorelease类似发送多个release消息,在内存池清空时会引起内存错误;·其次,即使release可以由autorelease

6、替代,也不能滥用autorelease。因为autorelease要比正常的release消耗资源更多。另外,不必要的推迟release操作无疑会导致占用大量内存,容易引起内存泄露。autorelease和retain多亏了autorelease,方法才能够创建能够自动释放的对象。但是,长时间持有对象是一种很常见的需求。在这种情形下,我们可以向对象发送retain消息,然后在后面手动的release。这样,这个对象实际上可以从两个角度去看待:·从函数开发者的角度,对象的创建和释放都是有计划的;·从函数调用者的角度,使用了retain之后,对象的生命期变长了(使用

7、retain将使其引用计数器加1),为了让对象能够正确地被释放,调用者必须负责将计数器再减1。我们来理解一下这句话。对于一个函数的开发者,如果他不使用autorelease,那么,他使用alloc创建了一个对象并返回出去,那么,他需要负责在合适的时候对这个对象做release操作。也就是说,从函数开发者的角度,这个对象的计数器始终是1,一次release是能够被正常释放的。此时,函数调用者却使用retain将计数器加1,但是开发者不知道对象的计数器已经变成2了,一次release不能释放对象。所以,调用者必须注意维护计数器,要调用一次release将其恢复至1。

8、Conveniencec

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。