objective-c - 为什么 ARC 仍然需要 @autoreleasepool?

标签 objective-c memory-management xcode4.2 automatic-ref-counting

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

@autoreleasepool {
    …
}

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


编辑:简明扼要地总结一下我从所有回答和评论中得到的:

新语法:

@autoreleasepool { … }

的新语法
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
…
[pool drain];

更重要的是:

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

最佳答案

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);
            }
        }
    }
}

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

更新: 另请参阅此答案 - https://stackoverflow.com/a/7950636/1068248 - 为什么 @autoreleasepool 与 ARC 无关。

更新: 我查看了这里发生的内部情况和 wrote it up on my blog .如果你看看那里,你会看到 ARC 到底在做什么,以及编译器如何使用新样式 @autoreleasepool 以及它如何引入范围来推断有关保留、释放和自动释放的信息是必需的。

关于objective-c - 为什么 ARC 仍然需要 @autoreleasepool?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9086913/

相关文章:

C程序——结构变量数据打包和对齐

objective-c - 从应用程序保存到联系人 : Nothing Happening/Error

ios - 自定义委托(delegate)问题

ios - Xcode 不在模拟器上运行该应用程序。 (应用程序意外退出)

objective-c - 按字典值返回对象的索引

ios - 下载 Xcode 4.2 文档以进行离线安装

objective-c - 无法以编程方式在 Xcode 4.2 中设置标签栏图像

ios - <CATransformLayer : 0x14fea3710> - changing property masksToBounds in transform-only layer, 将无效

c++ - 一个类的内存布局是连续的吗?

c++ - 如何正确处置注入(inject)的DLL线程?