Objective-C中的自动释放池 - 释放主AutoreleasePool?

eri*_*ell 6 memory-management objective-c autorelease nsautoreleasepool ios

根据我的理解,当一个对象被发送一条autorelease消息时,如果没有自动释放池存在main.m,那么该对象将被置于其中main.m.假设这是正确的,我有几个问题:

1)所有自动释放的对象是否都会留在该池中,直到应用程序终止?

2)如果1为真,那么创建一个没有本地自动释放池的自动释放对象(因此将该对象放入main.m池中)是否会将该对象保留在内存中,直到应用程序终止或收到内存警告为止?

3)main.m除了应用程序收到内存警告或应用程序终止之外,何时自动释放池耗尽?

例如,在cellForRowAtIndexPath委托方法中,例如:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Foobar"];
if (cell == nil) {
    // No cell to reuse => create a new one
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Foobar"] autorelease];

    // lots of custom stuff
}

return cell;
Run Code Online (Sandbox Code Playgroud)

细胞何时实际释放?它们必须是自动释放的,因为你不能在它们返回之前释放它们,并且之后你不能释放它们,因为它们超出了范围.根据我目前的理解,细胞被放置在最顶层的自动释放池中,并在该池被排空/释放时释放.在这种情况下,这将是应用程序中唯一的自动释放池; 那个人main.

4)这个问题,即使我完成了那些单元格并且视图控制器已经被释放,单元格仍留在内存中,是吗?如果不是这种情况,有人可以解释一下这种情况下的内存管理是如何工作的吗?谢谢!

注意:我查看了Apple的文档,但它主要讨论何时使用您自己的本地自动释放池,但没有太多关于它们实际运行的方式.

cbr*_*nch 7

文档:

Application Kit在事件循环的每个循环开始时在主线程上创建一个自动释放池,并在最后将其排出,从而释放处理事件时生成的任何自动释放的对象.如果您使用Application Kit,则通常不必创建自己的池.但是,如果您的应用程序在事件循环中创建了大量临时自动释放的对象,那么创建"本地"自动释放池以帮助最小化峰值内存占用量可能是有益的.

因此,默认池中的自动释放对象只能在当前事件的持续时间内存活.


Cal*_*leb 5

1)所有自动释放的对象是否都会留在该池中,直到应用程序终止?

根据定义,自动释放的对象由其自动释放池拥有,直到该池耗尽为止.发送-autorelease到对象时,该对象将添加到池稍后将释放的对象列表中.自动释放池以堆栈形式组织,堆栈顶部的池-autorelease是添加了任何发送对象的池.创建的池main()通常不是堆栈顶部的池.例如,运行循环将在每次迭代开始时创建自动释放池.

2)如果1为真,那么创建一个没有本地自动释放池的自动释放对象(因此将该对象放在main.m池中)会将该对象保留在内存中,直到应用程序终止或收到内存警告为止?

如果创建的池main()是最顶层的池,但如上所述,通常情况并非如此.

3)什么时候main.m自动释放池耗尽,除了应用程序收到内存警告或应用程序终止时?

创建的池main()与任何其他自动释放池之间没有区别.它们在池被释放时被耗尽,或者如果您使用该@autorelease指令则在块的末尾被耗尽.

  • "根据定义自动释放的对象由其自动释放池保留"这是不正确的.自动释放池不保留任何内容.自动释放只不过是一种延迟的消息机制.当您向对象发送-autorelease时,它不会增加其保留计数.它将对象添加到将在自动释放池本身被释放或发送-drain消息时将发送-release消息的对象列表. (8认同)
  • 另外几点:(1)自动释放池是每个线程,因此,自动释放的对象永远不能安全地在两个线程之间传递.(3)顶级游泳池可能永远不会被排空,因为没有意义; 如果一个应用程序被终止,它将发送最后的"我离开这里"通知,然后直接退出()而不用费力去除池. (3认同)