Autorelease Pools自动释放池概要

Autorelease Pools自动释放池概要,第1张

概述本篇将给您介绍”Autorelease Pools”(自动释放池)在应用中的使用技巧。 1,Autorelease Pools概要 一个”Autorelease Pool”实例中“包含”其它各种调用了”autorelease”方法的对象。当它释放时,其中所有被管理对象都会收到”relrease”的消信。注意,同一个对象可以被多次调用”autorelease”方法,并可以放到同一个”Autorele 本篇将给您介绍”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 总结

以上是内存溢出为你收集整理的Autorelease Pools自动释放池概要全部内容,希望文章能够帮你解决Autorelease Pools自动释放池概要所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1065638.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存