本篇将给您介绍”Autorelease Pools”(自动释放池)在应用中的使用技巧。

1,Autorelease Pools概要

一个”Autorelease Pool”实例中“包含”其它各种调用了”autorelease”方法的对象。当它释放时,其中所有被管理对象都会收到”relrease”的消信。注意,同一个对象可以被多次调用”autorelease”方法,并可以放到同一个”Autorelease Pool”中。引入这个自动释放池机制,对象的”autorelease”方法代替”relrease”方法可以延长它的生命周期,直接到当前”Autorelrease Pool”释放。如果想让此对象的生命周期超过”Autorelease Pool”,还可以再次”retain”,呵呵,有意思吧〜且让我慢慢道来。

Cocoa总是认为当前至少有一个”Autorelease Pool”对象是可用的。若此对象并不存在,你调用的”autorelease”的所有对象都不会被自动释放掉,可想而知,造成内存泄露。Cocoa把这个错误信息写入日志〜〜仅仅是为了以后分析。

你可以用”alloc”与”init”方法创建一个”NSAutoreleasePool”对象,并且可以调用”release”或”drain”(”release”与”drain”的区别是”drain”在有GC的环境中会引起GC回收操作,”release”反之。但在非GC环境中,两者相同。官方的说法是为了程序的兼容性,应该考虑用”drain”代替”release”,)方法来回收它(调用它的”autorelease”或”retain”方法会引起异常)。在一个完整的上下文最后”Autorelease Pool”对象应该被”release”掉(在方法内或一段循环体内创建的”Autorelease Pool”对象)。

“Autorelease Pools”的所有实例在栈中管理(我们暂时叫他“自动释放池栈”),并且它们是可以被嵌套的(父生子,子生孙。。。子子孙孙 ^_^)。例如,当我们创建一个”Autorelease Pool”对象后,它就被自动放到“自动释放池栈”的栈顶。当本池对象回收时,它就随之从这个栈中POP掉。那么也就是说,当任何一个对象调用”autorelease”方法后,它会被放入当前线程中当前栈顶的自动释放池中。

接下来我们聊聊”Autorelease Pools”的嵌套问题。在你的应用中,你可以任意多的创建”Autorelease Pool”对象,而这些对象被当前线程的“自动释放池栈”所管理。那么除了一个接一个的顺序创建并销毁它的情况外,还有一种使用方式,就是嵌套式的创建与使用。例如:在你的主函数创建了一个”autorelease pool”,然后又调用了创建了”autorelease pool”实例的其它方法;或是在外循环中创建了”Autorelease Pool”的实例,而内循环中也做了相同的事情。有意思吧,呵呵,嵌套的机制使父Pool实例释放后,它的所有子Pool也将释放。但这里还存在一些副作用,后续文章会详细讨论。

“Application kit”在一个事件循环里会自动创建一个”autorelease pool”。像鼠标键的按下与释放,所以你编写的代码通常不需要考虑太多这方面的事情。当然,有以下三种情况你会创建与销毁自己的Pool实例:

1,应用不是基于”Application Kit”,像”Command-line tool”,因为它并没有内置的”autorelease pools”的支持。
   2,创建线程,你必需在线程开始时创建一个”Autorelease Pool”实例。反之,会造成内存池露(会在以后的文章详细说明线程与池的技巧)。
   3,一个循环内创建了太多的临时对象,你应该为他们创建一个”Autorelease Pool”对象,并在下次循还前销毁它们。

2,自动释放池中的”Non-AppKit”应用

在”Non-AppKit”应用中使用自动释放池的机制其实是相当简单的事情。你仅仅需要在main()起始处创建”Autorelease Pool”对象,并在结尾处释放掉它。就像在Xcode的Foundation Tool的创建模版里写的一样。这个确保你在应用生命周期内至少有一个”Autorelease Pool”是可用的。但是,这也使所有在此期间的所有”autorelease”的对象都必需在应用结束后才被释放。这也许会引起在应用的使用中不断的增长,所以,你仍然考虑在不同的作用域创建新的”Autorelease Pool”。

大多应用中都存在各种级别的循环机制。在这些应用中,你可以在每个循环内的开头创建一个”Autorelease Pool”对象,并在结尾处释放掉它。

例如:

void main()
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSArray *args = [[NSProcessInfo processInfo] arguments];
    unsigned count, limit = [args count];

for (count = 0; count < limit; count++)
    {
        NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
        NSString *fileContents;
        NSString *fileName;

fileName = [args objectAtIndex:count];
        fileContents = [[[NSString alloc] initWithContentsOfFile:fileName] autorelease];
        // this is equivalent to using stringWithContentsOfFile:

/* Process the file, creating and autoreleasing more objects. */

[loopPool release];
    }

/* Do whatever cleanup is needed. */
    [pool drain];

exit (EXIT_SUCCESS);
}

在命令行中处理所有以参数传来的文件。一次循环处理一个文件。在循环的开头创建一个”NSAutoreleasePool”对象,并在循环结束时释放掉。因此,任何在其中创建并调用“autorelease”的对象都将添加到这个Pool实例中,当本池被释放后,这些对象也将被回收。注意,任何在作用域内创建的”autoreleased”对象(像”fileName”),虽然并没有显示的调用”autorelease”方法,但都将被当前池所管理并释放。

先到这里,休息,休息一下〜〜

本文翻译自:
http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-SW2

转载于:https://www.cnblogs.com/greywolf/archive/2012/11/22/2782440.html

(转)Objective-C Autorelease Pools(自动释放池)详解相关推荐

  1. iOS中内存自动释放池

    自动释放池 iOS应用的主线程在每次runloop开始的时候创建自动释放池,在runloop结束的时候释放自动释放池.如果在一个runloop内,应用程序创建了大量临时对象,自动释放池可以减少内存峰值 ...

  2. ios中的自动释放池

    自动释放池中是否有虑重功能 1 @autoreleasepool { 2 UIView *view = [UIView alloc] init] autorelease]; 3 [view autor ...

  3. 内存管理-定时器循环、内存布局、tagged pointer、weak指针、copy、自动释放池

    先上代码,我们平时用的定时器,cadisplaylink.nstimer,CADisplayLink.NSTimer会对target产生强引用,如果target又对它们产生强引用,那么就会引发循环引用 ...

  4. 自动释放池autoreleasepool

    自动释放池是NSAutoreleasePool的实例,其中包含了收到autorelease消息的对象.当一个自动释放池自身被销毁(dealloc)时,它会给池中每一个对象发送一个release消息(如 ...

  5. 【深入Cocos2d-x】探索Cocos2d-x中的内存管理-引用计数和自动释放池

    2019独角兽企业重金招聘Python工程师标准>>> #深入Cocos2d-x-探索Cocos2d-x中的内存管理-引用计数和自动释放池 ###引用计数(Reference Cou ...

  6. 第六讲:Obj-C 内存管理4 - 自动释放池

    转:http://tigercat1977.blog.163.com/blog/static/2141561122012111294616203/ 第六讲:Obj-C 内存管理4 - 自动释放池 主要 ...

  7. cocos2d-x游戏开发(六)自动释放池

    欢迎转载:http://blog.csdn.net/fylz1125/article/details/8519887 上一篇文章写了引用计数和自动释放的大概流程,其中略过了自动释放池,这里简单述说. ...

  8. Objective-c自学笔记(5)-自动释放池

    解决的问题 每一个东西的产生都是在实际生活迫切需要这样的东西后,人们通过思考发明创造某些东西用以解决这个问题.那么自动释放池用来解决什么问题?请看下面的例子: 对于一些有返回值的消息(方法),它返回的 ...

  9. 自动释放池 ARC机制

    IOS学习第24天 @class 1.两个类A和B,如果互相#import对方头文件,会造成死循环2.解决方式: 在其中的一方,不要用#import <xxx.h>来引入对方的头文件,用@ ...

最新文章

  1. excel 解析 java_java解析Excel(xls、xlsx两种格式)
  2. heritrix 3.2.0 -- 环境搭建
  3. c语言申请字符串动态,【分享】C语言动态长度字符串
  4. 网站优化数据分析不建议你遗落这三点
  5. DPDK pmd驱动初始化(十九)
  6. Ehcarts 与 百度地图结合时,如何获取bmap的实例对象?
  7. 记一次OpenJDK替换java JDK
  8. yapi 接口文档_1分钟docker部署顶尖 API 文档管理系统
  9. 使用多线程拷贝文件夹
  10. 设计模式之美 - 64状态模式
  11. jQuery系列之目录汇总
  12. 转载:jillzhang的文章索引 包括(Nhiberate,WCF,WPF,项目管理等内容)
  13. FPGROWTH算法
  14. 业界通用代码检查工具(针对C语言)
  15. 条件数、奇异值与海森矩阵
  16. Angular基本概念及用法总结
  17. MindSpore布道师招募计划,开启AI的信仰之跃
  18. 系统盘修复计算机命令,U盘启动盘修复系统的详细步骤
  19. Jmeter压力测试_token参数化
  20. No7.装饰器的进阶

热门文章

  1. 诺顿本月将发布儿童网络安全软件
  2. 四、Delphi 2009 泛型容器单元(Generics.Collections)[3]: TStackT
  3. Discuz! $_DCACHE数组变量覆盖漏洞
  4. php 修改css 不生效,HTML外部引用CSS文件不生效原因分析及解决办法
  5. java 统计图 mysql_java实现各种数据统计图(转)
  6. Nginx七层负载均衡配置
  7. 搭建基础架构-ResultMsg
  8. SpringBoot_数据访问-JDBC自动配置原理
  9. mysql触发器如果某个字段被修改_mysql trigger触发器 一张表一个字段改变 更新另一张表对应字段...
  10. Hive--优化参数