【问题标题】:When do autorelease pools drain?自动释放池何时耗尽?
【发布时间】:2015-08-11 11:21:21
【问题描述】:

我研究手动内存管理,我想知道自动释放池何时耗尽。

我发现有 3 种情况: 1 - 在main.m 中,从应用程序运行开始并在结束时耗尽,因此释放内存中的所有对象。 2 - 当您手动显式创建自动释放池并将其耗尽时

第三种情况是我所要求的,这让我有点困惑。

正如我所研究的,自动释放对象就像 C 中的自动变量一样,只存在于逻辑范围内(在函数体中)。因此,我假设每个函数后面都有一个隐藏的[pool drain];

但是,有人向我指出,这并不像我想的那样正确。苹果公司表示,它在“事件”之后会耗尽。该事件可能在用户点击按钮时发生,例如重新加载表格视图。

但这些信息不足以了解全貌。您能否为我澄清一下,什么时候池中的物体会耗尽,比如NSArray *arr = [NSArray array];

【问题讨论】:

  • 自动释放池不会在每个函数结束时耗尽,而是在每次将控制权交还给运行循环时。
  • @Rob 这就是我所要求的,什么时候发生?
  • @rob 好的,这很好,但是我怎么能确定哪种方法确实会耗尽池?有方法列表吗?还是一些标准?
  • @Rob 但是有很多方法调用“幕后”,比如 NSObject +load。显然,池在任何 NSObject 加载时都不会耗尽。我喜欢你的解释,但仍然看不到全貌:)

标签: ios objective-c memory-management


【解决方案1】:

文档没有具体说明“主”自动释放池何时耗尽,但通常您可以假设它在应用程序的主事件循环结束时被耗尽。

关于自动释放池的情况如下:

  1. 应用程序启动时会创建一个自动释放池。
  2. 当另一个池被创建时,它被添加到自动释放池堆栈的顶部。
  3. autorelease 被发送到对象时,它会被添加到堆栈顶部的自动释放池中。
  4. release 发送到自动释放池时,它会依次将release 发送到池中的任何对象。

#4 通常在主事件循环结束时自动发生(对于主自动释放池)。

NSAutoreleasePool 的文档有更多信息,包括这个相关的花絮:

Application Kit 在事件循环的每个循环开始时在主线程上创建一个自动释放池,并在结束时将其排空,从而释放在处理事件时生成的所有自动释放对象。

【讨论】:

  • 我很抱歉,但对我来说仍然很不清楚。如果我理解正确,主事件循环是主线程,它在应用程序启动时开始,在它完成运行时结束。我知道当应用程序结束时,main 中的自动释放池会耗尽。但是在应用程序的生命周期中必须释放的对象呢?明显地。应用程序不能在内存中“保存”所有对象,直到它结束,因此,它必须弄清楚何时需要耗尽其他池,否则应用程序将耗尽内存。我想知道它是如何以及何时耗尽这些水池的。
  • @EvgeniyKleban:主事件循环在应用程序的生命周期内不断循环(因为它必须处理 UI 事件),因此主自动释放池将在应用程序的生命周期内多次耗尽。
  • 我认为有几个池,每个池中都有一些对象,并且在某些情况下会耗尽。但是,如果只有 1 个池并且它多次耗尽,那么所有自动释放的对象在生命周期中都会被多次销毁?那是对的吗? (只有保留计数 > 1 的存活)
  • @EvgeniyKleban:当池耗尽时,它会删除正在跟踪的对象并向其发送release 消息。 (嗯,它有点复杂——一个对象可以多次添加到自动释放池中——但从概念上讲,你可以认为它是这样工作的。)所以一个对象只会收到一个 release 消息每个autorelease 收到的消息。
  • @gaussblurinc:是的。事件循环在应用程序的整个生命周期内持续,并且堆栈顶部的自动释放池(通常在主事件循环结束时应该是唯一的)将被耗尽。
【解决方案2】:

当我使用逆向工程工具来分析 Foundation 框架时。然后我发现在运行循环开始时创建了自动释放池并在运行循环结束时释放。 图片:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多