小编典典

为什么 ARC 仍然需要 @autoreleasepool?

all

在大多数情况下,使用 ARC(自动引用计数),我们根本不需要考虑 Objective-C
对象的内存管理。不再允许创建NSAutoreleasePools,但是有一种新语法:

@autoreleasepool {
    …
}

我的问题是,当我不应该手动释放/自动释放时,为什么我需要这个?


编辑: 总结一下我从所有答案和评论中得到的简洁:

新语法:

@autoreleasepool { …}是新的语法

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
…
[pool drain];

更重要的是:

  • ARCautoreleaserelease.
  • 它需要一个自动释放池来执行此操作。
  • ARC 不会为您创建自动释放池。 然而:
    • 每个 Cocoa 应用程序的主线程中已经有一个自动释放池。
  • 有两种情况您可能想要使用@autoreleasepool
    1. 当你处于辅助线程并且没有自动释放池时,你必须自己制作以防止泄漏,例如myRunLoop(… { @autoreleasepool { … return success; }.
    2. 当您希望创建一个更本地的池时,正如@mattjgalloway 在他的回答中所示。

阅读 73

收藏
2022-07-02

共1个答案

小编典典

ARC 并没有摆脱保留、发布和自动发布,它只是为您添加所需的内容。所以仍然有保留的调用,仍然有释放的调用,仍然有自动释放的调用,还有自动释放池。

他们使用新的 Clang 3.0 编译器和 ARC
进行的其他更改之一是它们替换NSAutoReleasePool@autoreleasepool编译器指令。NSAutoReleasePool无论如何,它总是有点特殊的“对象”,他们这样做是为了使使用
one 的语法不会与对象混淆,因此它通常更简单一些。

所以基本上,你需要@autoreleasepool因为仍然需要担心自动释放池。您只是无需担心添加autorelease呼叫。

使用自动释放池的示例:

- (void)useALoadOfNumbers {
    for (int j = 0; j < 10000; ++j) {
        @autoreleasepool {
            for (int i = 0; i < 10000; ++i) {
                NSNumber *number = [NSNumber numberWithInt:(i+j)];
                NSLog(@"number = %p", number);
            }
        }
    }
}

当然,这是一个非常人为的例子,但是如果您没有@autoreleasepool外部循环内部,for那么您稍后将释放 100000000
个对象,而不是每次围绕外部循环释放 10000 个对象for

更新: 我查看了这里发生的内部情况并将其写在我的博客上。如果您看一下那里,您将确切地看到 ARC
正在做什么,以及@autoreleasepool编译器如何使用新样式以及它如何引入范围来推断有关需要保留、发布和自动发布的信息。

2022-07-02