iOS编程自动释放池

时间:2012-08-31 16:05:30

标签: objective-c ios autorelease

Apple documentation中,它说:

  

AppKit和UIKit框架处理每个事件循环迭代   (例如,鼠标按下事件或点按)在自动释放池中   块。因此,您通常不必创建自动释放   池自己阻止,甚至看到用于创建一个的代码。

现在,这应该是显而易见的,但无论如何我都会要求确认。

如果我正在开发最终的后台进程(通过Grand Central Dispatch),但为了简单起见,我首先将它放在第一个加载视图的viewDidLoad中,以便我的视图实际上不会显示在屏幕直到所有(比如说)2分钟的处理完成,然后在这两分钟内,所有默认的自动释放池都没有被释放,因为它还没有通过事件循环迭代,对吧?听到一个没有,这简直就是疯了,但我陷入了这个不断增长的记忆问题,所以我要求确认并希望得到一个好消息。

如果是这样,我应该放置自己的自动释放块。如果通过GCD在后台进程中完成处理,我仍然需要autorelease块,对吧?

2 个答案:

答案 0 :(得分:4)

我会尽力给你一个完整的答案。

第一部分。首先要注意主线程中长时间运行的操作。例如,如果您的操作需要两分钟,则主线程将被阻塞,直到完成为止。从用户的角度来看,该应用程序将无法响应两分钟。 无论如何,是的,在应用程序委托中有一个池,其中插入了自动释放的对象。当循环结束时,池中的对象将被释放,因为池会自动排空。 如果您有记忆问题,可以查看Use Local Autorelease Pool Blocks to Reduce Peak Memory Footprint。如在doc中编写的那样,您应该将操作包装在autorelease块中。在块结束时,临时对象被释放,这通常会导致释放,从而减少程序的内存占用。

关于GCD问题,我会说不。处理GCD时,您不必创建自动释放池。通常,同样在Do you need to create an NSAutoreleasePool within a block in GCD?中编写,GCD自动管理每个队列的自动释放池。所以,如果你有很少的对象,你不必担心它,但如果你创建了很多对象,是的,创建一个自动释放池。后者允许您减少内存占用。

  

因此,对于应用程序无法响应的整整两分钟,   它是循环尚未结束的时间,并且在此期间池没有耗尽   这两分钟吧?

应用程序没有响应,因为主线程(通过运行循环)按顺序执行任务。如果您阻止运行循环,应用程序将冻结,直到长时间运行操作完成(我认为如果超过特定时间段,应用程序将被iOS杀死)。为避免这种情况,您可以在另一个线程中执行(如您所写)长时间运行的操作。

使用线程的目的是使应用程序具有高响应性,但它​​可能导致各种问题,如不一致的数据(竞争条件)或死锁

有关详细信息,我建议您阅读The pogo stick of NSRunLoopUnderstanding NSRunLoopNSDefaultRunLoopMode vs NSRunLoopCommonModes

答案 1 :(得分:0)

您不需要创建自己的自动释放块来管理自动释放对象的内存; 一个池, 自动管理,自动释放的对象 最终将被释放。

因此,唯一的问题是“最终”这个神奇的词。在您处理过程中,您的应用程序是否使用了太多内存(例如,系统会将其杀死的内存太大),因为尚未发布 的自动释放对象?请记住,他们被释放;问题是情况是否如此糟糕以至于你需要释放它们现在,而不是等待自动释放池的耗尽,当然发生而你没有采取任何行动

只有仪器可以告诉你,所以不要猜测,不要过早优化;看看乐器揭示了什么。如果情况那么糟糕,那么确定,找到生成所有这些自动释放对象的循环并在其中放入一个自动释放块,以便每次循环时池都被耗尽。否则,真的没有必要。 (另一方面,在ARC下,自动释放块增加了非常少的开销,因此它可能不会做太多伤害来过早优化。)