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

在大多数情况下,使用 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 以及它如何引入范围来推断有关保留、释放和自动释放的信息是必需的。

https://stackoverflow.com/questions/9086913/

相关文章:

ios - UICollectionView 中的单元格间距

objective-c - 在 Objective-C 中,Java 的 "instanceof"关

ios - UITableViewCell 显示白色背景,在 iOS7 上无法修改

objective-c - Xcode 5 中提供了哪些新的文档命令?

objective-c - 禁用某些文件的自动引用计数

c - Objective-C : BOOL vs bool

objective-c - respondsToSelector 的 Swift 等价物是什么?

objective-c - 在 Objective-C 中将 NSArray 转换为 NSStrin

objective-c - 洗牌 NSMutableArray 的最佳方法是什么?

ios - 如何对字符串进行 URL 编码