在ARC下,是否仍然建议为循环创建一个@autoreleasepool?

Tim*_*ddy 19 memory-management objective-c nsautoreleasepool automatic-ref-counting

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

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

在ARC下,我是否仍然应对@autoreleasepool这种while情况?

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

我之所以问的原因是我看到我的NSData对象通过屋顶的工具中的生活分配数量调用dataWith...方法而不是initWith...方法.当我使用时initWith...,生活分配数量要少得多.

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

log*_*ell 13

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

链接

  • Per @ Chuck的答案:@autoreleasepool需要*循环*循环,以便它做任何好事.成语是`while(x)@autoreleasepool {...}`,而不是`@autoreleasepool {while(x){...}}`. (10认同)

Chu*_*uck 13

我认为你的问题是自动释放池应该进入循环内部.使用自动释放块内的循环而不是反之亦然,累积的对象直到循环结束后才会释放.


jus*_*tin 7

在ARC下,我是否还应该围绕while条件包装一个@autoreleasepool?

是.自动释放池仍然存在,并像以前一样成长和弹出.根据TU可见的方法和默认命名约定,编译器只是在启用ARC(回显Logan)时添加并合并必要的保留和释放操作.

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

是否可能更喜欢initWith ...方法?

与自动释放的对应物相比,WRT最小化堆增长:是的.情况一直如此.在iOS设备上尤为重要,因为内存非常有限.

例外情况是对象可能避免分配.例:

NSString * copy = [NSString stringWithString:arg];
Run Code Online (Sandbox Code Playgroud)

在这种情况下,copy可能是[[arg retain] autorelease].请注意,在这种情况下,copy仍然是自动释放的,但您通常不应该竭尽全力测试此类优化的存在.注意:这里使用copy = [arg copy]... 也更好[arg release].

另一个好处是,当对象从未自动释放时,并且更靠近调用站点(而不是最终弹出自动释放池时),通常会更早地捕获引用计数不平衡.

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