假设我有一个返回一堆自动释放的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...
方法吗?
答案 0 :(得分:13)
是的,在紧密循环中使用便捷方法时,您仍应使用自动释放池。所有旧的内存管理规则仍然适用于ARC,编译器只是为您注入RR。通过令人敬畏的迈克·阿什查看精彩帖子!
答案 1 :(得分:13)
我认为您的问题是自动释放池应该在内部循环中。使用自动释放块内的循环而不是反之亦然,累积的对象将在循环结束后才会释放。
答案 2 :(得分:7)
在ARC下,我是否仍然围绕while条件包装@autoreleasepool?
是。自动释放池仍然存在,并像以前一样成长和弹出。根据TU可见的方法和默认命名约定,编译器只是在启用ARC(回显Logan)时添加并合并必要的保留和释放操作。
ARC中的执行几乎与手动引用计数相同:自动释放池堆栈仍然存在。一个区别是编译器可能命令引用计数操作与您编写它的方式略有不同(不是以不正确的方式),并且可能省略不必要的保留周期。
尽可能优先选择initWith ...方法吗?
WRT最小化堆增长与自动释放的同行相比:是的。情况一直如此。这对于内存非常有限的iOS设备尤为重要。
此异常是指对象可能避免分配。示例:
NSString * copy = [NSString stringWithString:arg];
在这种情况下,copy
可能是[[arg retain] autorelease]
。请注意,在这种情况下,copy
仍然是自动释放的,但您通常不应该花很多时间来测试是否存在此类优化。注意:最好在这里使用copy = [arg copy]
... [arg release]
。
另一个好处是,当对象永远不会自动释放时,并且更靠近调用站点(而不是最终弹出自动释放池时),您的引用计数不平衡通常会更早被捕获。
大型自动释放池的性能实际上比大多数人想象的要糟糕得多。如果您可以避免严重依赖它们(例如使用alloc
+ init
... + release
),则可以使您的程序明显更快。明确地创建自动释放池很便宜,并且可以帮助最小化此问题。当分配很大和/或数量很多时,尽可能避免在它们上使用autorelease
,并将这些部分包装在显式自动释放池中。