【问题标题】:@autoreleasepool semantics@autoreleasepool 语义
【发布时间】:2011-12-09 22:05:57
【问题描述】:

我正在阅读 llvm 网站上的 ARC 文档:http://clang.llvm.org/docs/AutomaticReferenceCounting.html#autoreleasepool

..特别是关于@autoreleasepool。

在当前使用 NSAutoreleasePool 的许多实现中,我看到在循环迭代期间池会定期耗尽的情况 - 我们如何使用 @autorelease 池执行相同的操作,或者这一切都是在引擎盖下为我们完成的?

其次,文档指出,如果抛出异常,池不会被耗尽....好的异常是异常的,但如果它们确实发生,您可能希望在不泄漏内存负载的情况下恢复。文档没有指定这些对象何时发布。

有人知道关于这些点的任何信息吗?

【问题讨论】:

    标签: objective-c llvm automatic-ref-counting


    【解决方案1】:

    在当前使用 NSAutoreleasePool 的许多实现中,我看到在循环迭代期间池会定期耗尽的情况 - 我们如何使用 @autorelease 池执行相同的操作,或者这一切都是在引擎盖下为我们完成的?

    以同样的方式,即通过级联自动释放池。例如:

    @autoreleasepool {
        …
        for (int i = 0; i < MAX; i++) {
            @autoreleasepool {
                …
            }
        }
        …
    }
    

    其次,文档指出,如果抛出异常,池不会被耗尽....好的异常是异常的,但如果它们确实发生,您可能希望在不泄漏内存负载的情况下恢复。文档没有指定这些对象何时发布。

    在大多数情况下,由于 Cocoa 中异常的特殊性质,程序将无法正常恢复,所以我会说泄漏对象是一个较小的问题。如果@autoreleasepool 块因为异常而退出,则相应的自动释放对象只会在其中一个封闭的自动释放池被弹出时才会被释放。但是你当然可以在@autoreleasepool 块内放置@try/@catch/@finally 块来防止这种情况发生。

    【讨论】:

    • 我认为您回答的第二部分不太正确。自动释放池本身在分配时有效的自动释放池中自动释放。只要异常没有传播到最外层的自动释放池之外,就不会泄漏任何自动释放的对象。
    • @Bavarious - 感谢您的出色回答。可以肯定的是,它在使用stringWithFormat 时会在循环中泄漏内存。
    【解决方案2】:

    我们如何对@autorelease pool 做同样的事情

    像这样:

    for (int i = 0; i < 10000; i++) {
        @autoreleasepool {
            // Do your work here
            ...
        }
    }
    

    其次,文档指出,如果抛出异常,池不会被耗尽....好的异常是异常的,但如果它们确实发生,您可能希望在不泄漏内存负载的情况下恢复。

    AFAIK 这在 ARC 中是不可能的。 ARC 根本不是异常安全的。如果发生异常,则可能存在不可恢复的内存泄漏。使用 ARC 的代码不应依赖异常来报告错误。期望是当引发异常时进程无论如何都会崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-18
      • 2013-07-20
      • 2011-05-12
      • 2016-05-24
      • 1970-01-01
      相关资源
      最近更新 更多