在大多数情况下,使用 ARC(自动引用计数),我们根本不需要考虑使用 Objective-C 对象的内存管理。不再允许创建 NSAutoreleasePool
,但是有一个新的语法:
@autoreleasepool {
…
}
我的问题是,当我不应该手动释放/自动释放时,为什么我还需要这个?
编辑:简明扼要地总结一下我从所有回答和评论中得到的:
新语法:
@autoreleasepool { … }
是
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
…
[pool drain];
更重要的是:
- ARC 使用
autorelease
以及release
。 - 它需要一个自动释放池来执行此操作。
- ARC 不会为您创建自动释放池。 但是:
- 每个 Cocoa 应用的主线程中都已经有一个自动释放池。
- 在两种情况下您可能想要使用
@autoreleasepool
:- 当你处于辅助线程且没有自动释放池时,你必须自己制作以防止泄漏,例如
myRunLoop(...) { @autoreleasepool { ... } return success; }
。 - 当您希望创建一个更本地化的池时,正如 @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/