【问题标题】:Under ARC, is it still advisable to create an @autoreleasepool for loops?在 ARC 下,是否仍然建议为循环创建一个 @autoreleasepool?
【发布时间】:2011-12-11 04:14:45
【问题描述】:

假设我有一个循环,它返回一堆自动释放的 NSData 对象...

NSData* bigData = ...
while(some condition) {
    NSData* smallData = [bigData subdataWithRange:...];
    //process smallData
}

在 ARC 下,我是否仍应将 @autoreleasepool 包裹在 while 条件周围?

NSData* bigData = ...
@autoreleasepool {
    while(some condition) {
        NSData* smallData = [bigData subdataWithRange:...];
        //process smallData
    }
}

我问的原因是我看到我的 NSData 对象调用dataWith... 方法而不是initWith... 方法的仪器中的活分配计数。当我使用initWith... 时,生活分配数非常非常少。

尽可能选择initWith... 方法会更好吗?

【问题讨论】:

    标签: objective-c memory-management automatic-ref-counting nsautoreleasepool


    【解决方案1】:

    是的,在紧密循环中使用便捷方法时,您仍应使用自动释放池。所有旧的内存管理规则仍然适用于 ARC,编译器只是为您注入 RR。查看很棒的 Mike Ash 的精彩帖子!

    Link

    【讨论】:

    • 根据@Chuck 的回答:@autoreleasepool 需要进入 inside 循环才能发挥作用。成语是while (x) @autoreleasepool { ... },而不是@autoreleasepool { while (x) { ... } }
    • 这过于简单且不正确。 ARC 通常可以针对返回 +0 对象的方法优化自动释放池的使用(这是autorelease 的最常用用法)。
    【解决方案2】:

    我认为您的问题是自动释放池应该进入循环内部。使用 autorelease 块内的循环而不是反之亦然,累积的对象在循环结束之前不会被释放。

    【讨论】:

    • 我没有想过将@autoreleasepool 放在循环中...谢谢您的提示。
    【解决方案3】:

    在 ARC 下,我是否仍应将 @autoreleasepool 包裹在 while 条件周围?

    是的。自动释放池仍然存在,并且像以前一样增长和流行。当启用 ARC(与 Logan 相呼应)时,编译器仅根据对 TU 可见的方法和默认命名约定添加和合并必要的保留和释放操作。

    ARC 中的执行几乎与手动引用计数相同:自动释放池堆栈仍然存在。一个区别是编译器可能对引用计数操作的排序与您编写它的方式略有不同(不是以不正确的方式),并且可能会省略不必要的保留周期。

    尽可能选择 initWith... 方法会更好吗?

    与自动发布的同类产品相比,WRT 最大限度地减少了堆增长:是的。情况一直如此。这在内存非常有限的 iOS 设备上尤为重要。

    例外情况是对象可以避免分配。示例:

    NSString * copy = [NSString stringWithString:arg];
    

    在这种情况下,copy 可能是 [[arg retain] autorelease]。请注意,在这种情况下,copy 仍然是自动发布的,但您通常不应该费尽心思去测试这种优化是否存在。注意:这里最好使用copy = [arg copy]...[arg release]

    另一个好处是,当对象从不自动释放时,您的引用计数不平衡通常会更早发现,并且更靠近调用站点(而不是在自动释放池最终弹出时)。

    大型自动释放池的性能实际上比大多数人想象的要差得多。如果你可以避免过度依赖它们(例如使用alloc+init...+release),你可以让你的程序明显更快。显式创建自动释放池很便宜,并且可以帮助最小化这个问题。当分配很大和/或很多时,尽可能避免在它们上使用autorelease,并将这些部分包装在显式的自动释放池中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-04
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      相关资源
      最近更新 更多