为什么 ARC 仍然需要@autoreleasepool? [英] Why is @autoreleasepool still needed with ARC?

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

问题描述

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

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 使用 autoreleaserelease.
  • 它需要一个自动发布池来做到这一点.
  • 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 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 个对象而不是每次围绕外部 for 循环 10000.

    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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆