本文介绍了为什么 ARC 仍然需要 @autoreleasepool?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For the most part with ARC (Automatic Reference Counting), we don't need to think about memory management at all with Objective-C objects. It is not permitted to create NSAutoreleasePools anymore, however there is a new syntax:

@autoreleasepool {
    …
}

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

My question is, why would I ever need this when I'm not supposed to be manually releasing/autoreleasing ?

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

To sum up what I got out of all the anwers and comments succinctly:

新语法:

@autoreleasepool { … }

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

更重要的是:

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

  • 推荐答案

    ARC 并没有摆脱保留、释放和自动释放,它只是为您添加所需的.所以仍有调用保留,仍有调用释放,仍有调用自动释放,仍有自动释放池.

    ARC doesn't get rid of retains, releases and autoreleases, it just adds in the required ones for you. So there are still calls to retain, there are still calls to release, there are still calls to autorelease and there are still auto release pools.

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

    One of the other changes they made with the new Clang 3.0 compiler and ARC is that they replaced NSAutoReleasePool with the @autoreleasepool compiler directive. NSAutoReleasePool was always a bit of a special "object" anyway and they made it so that the syntax of using one is not confused with an object so that it's generally a bit more simple.

    所以基本上,您需要 @autoreleasepool 因为仍然需要担心自动释放池.您无需担心添加 autorelease 调用.

    So basically, you need @autoreleasepool because there are still auto release pools to worry about. You just don't need to worry about adding in autorelease calls.

    使用自动释放池的示例:

    An example of using an auto release pool:

    - (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-循环.

    A hugely contrived example, sure, but if you didn't have the @autoreleasepool inside the outer for-loop then you'd be releasing 100000000 objects later on rather than 10000 each time round the outer for-loop.

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

    Update:Also see this answer - https://stackoverflow.com/a/7950636/1068248 - for why @autoreleasepool is nothing to do with ARC.

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

    Update:I took a look into the internals of what's going on here and wrote it up on my blog. If you take a look there then you will see exactly what ARC is doing and how the new style @autoreleasepool and how it introduces a scope is used by the compiler to infer information about what retains, releases & autoreleases are required.

    这篇关于为什么 ARC 仍然需要 @autoreleasepool?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-20 09:37