自动释放池何时释放?

7

我正在学习手动内存管理,想知道自动释放池(autorelease pools)是何时释放的。

根据我的研究,有以下3种情况: 1 - 在main.m文件中,从应用程序运行开始到结束时进行释放,因此释放内存中的所有对象。 2 - 当您手动创建一个自动释放池并将其释放时。

第三种情况是我询问的,这对我来说有点困惑。

据我所学,自动释放对象就像C语言中的自动变量,只存在于逻辑范围内(在函数体中)。 因此,我认为在每个函数之后都有一个隐藏的[pool drain];

但是,有人指出这不像我想象的那样正确。苹果公司表示,它会在“事件”之后进行释放。例如,当用户点击按钮、表格视图重新加载等事件发生时。

但这些信息还不足以完整地了解整个情况。 您能否为我澄清一下,例如NSArray *arr = [NSArray array];这样的对象何时释放?


1
自动释放池并不会在每个函数结束时被清空,而是在每次将控制权交还给运行循环时才会被清空。 - Rob
@Rob,那就是我所问的,那会发生在什么时候? - Evgeniy Kleban
@rob 好的,那很不错,但我怎么确定哪个方法确切地进行了池排放?有方法列表吗?或者一些标准? - Evgeniy Kleban
@Rob 但是有很多方法是在“幕后”被调用的,比如NSObject +load。显然,池不会在任何时候排空NSObject load。我喜欢你的解释,但仍然看不到整个画面 :) - Evgeniy Kleban
让我们在聊天中继续这个讨论:点击此处进入聊天室 - Rob
2个回答

9
文档没有明确说明“main”自动释放池何时被清空,但通常您可以假定它会在应用程序的主事件循环结束时清空。
以下是有关自动释放池的情况:
1. 当应用程序启动时,会创建一个自动释放池。 2. 创建另一个池时,它将添加到自动释放池堆栈的顶部。 3. 当向对象发送autorelease时,它将被添加到堆栈顶部的自动释放池中。 4. 当向自动释放池发送release时,它会转而向池中任何对象发送release
通常情况下(对于主自动释放池),#4会在主事件循环结束时自动发生。 NSAutoreleasePool 的文档提供了更多信息,包括以下相关片段: 引用块:The Application Kit creates an autorelease pool on the main thread at the beginning of every cycle of the event loop, and drains it at the end, thereby releasing any autoreleased objects generated while processing an event.

1
很抱歉,但对我来说仍然不太清楚。如果我理解正确,主事件循环是主线程,在应用程序启动时开始,在运行结束时结束。我了解到主要自动释放池在应用程序结束时被排空。但是,在应用程序的生命周期内必须释放的对象怎么办?显然,应用程序不能将所有对象保留在内存中直到结束,因此,它必须找出何时需要排空其他池,否则应用程序将耗尽内存。我想知道它是如何以及何时排空这些池的。 - Evgeniy Kleban
1
@EvgeniyKleban:主事件循环在应用程序的生命周期内不断循环(因为它必须处理UI事件),因此主自动释放池将在应用程序的生命周期内被多次清空。 - mipadi
我原以为有几个池子,每个池子里都有一些对象,并在某些情况下进行排放。但如果只有一个池子并且它多次排放,那么所有自动释放的对象在其生命周期内都会被多次销毁吗?这是正确的吗?(只有保留计数> 1的对象才能幸存) - Evgeniy Kleban
@EvgeniyKleban:当一个池子被排空时,它会移除正在追踪的对象并发送一个“release”消息。(嗯,这有点复杂——一个对象可以被添加到自动释放池中多次——但从概念上来说,你可以认为它是这样工作的。)因此,一个对象只会收到每个“autorelease”消息一次“release”消息。 - mipadi
1
@gaussblurinc:是的。事件循环将持续整个应用程序的生命周期,位于堆栈顶部的自动释放池(通常在到达主事件循环的末尾时应该是唯一的)将被清空。 - mipadi
显示剩余3条评论

4

当我使用反向工程工具分析Foundation框架时,发现自动释放池在运行循环开始时创建,在运行循环结束时释放。

autorelease start at runloop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接