@autoreleasepool循环或循环@autoreleasepool?

时间:2012-04-12 09:58:13

标签: iphone objective-c

在循环操作中将大量自动释放的对象放入autoreleasepool中是一种很好的做法。我发现有人把@autoreleasepool放在循环中,但其他人把循环放在@autoreleasepool中。

1:

while ([rs next]) {
    @autoreleasepool {
        NSDictionary *dict = [self dictFromXX];
        //...
    }
}

2:

@autoreleasepool {
    while ([rs next]) {
        NSDictionary *dict = [self dictFromXX];
        //...
    }
}

哪个更好?或者代码1和2之间有什么区别?

谢谢!

6 个答案:

答案 0 :(得分:29)

在每次迭代的第一个示例中,池都已耗尽。如果迭代的主体涉及大量自动释放的对象,这是有道理的。

第二个例子只会在循环后消耗池一次。

因此,如果循环的内部导致内存膨胀,那么请选择第一个选项。如果整个循环中的内存膨胀是可接受的,则循环然后使用选项2。

答案 1 :(得分:3)

在第一个示例中,autoreleasepool是在迭代开始时创建的,并且已经耗尽并且迭代结束。 在第二种情况下,池创建一次,并且仅在循环完成后销毁。如果您使用第二个变体,那么您可以获得大量内存开销,因为所有自动释放的对象仅在结尾处被释放。但是,您应该考虑需要处理的数据量。在大多数情况下,第二种变体是更优选的。

答案 2 :(得分:1)

我会选择第2版。

当块完成时,@autoreleasepool块将释放收到autorelease的所有对象。这需要时间,因为它需要一些cpu周期,并且根据对象,使用的时间可能比预期的要高得多。

我认为自定义@autoreleasepool仅在处理许多数据时才有意义> 20MB或在非主线程中使用数据。

因此。我建议避免“短”@autoreleasepool。因为它可能会减慢你的执行速度。

答案 3 :(得分:0)

以下是Core Data与autoreleasepools的不同方法:

Testing Core Data with very big hierarchical data sets的{p> Efficiently Importing Data 对你来说很重要的是Wrap the contents of the outer loop in an NSAutoreleasePool init/release and NSManagedObjectContext save解决方案。

答案 4 :(得分:0)

取决于将释放多少待处理项目。 Autorelease Pool就像你的垃圾一样,把未使用过的东西放进去的图片。

答案 5 :(得分:0)

  

@autoreleasepool块比直接使用NSAutoreleasePool的实例更有效;即使您不使用ARC,也可以使用它们。 - NSAutoreleasePool Class Reference

您通常不需要自动释放池,如果您这样做是因为您处于循环中并自动释放大量对象,那么当您尝试避免循环正在创建的峰值时,选项1比2更有意义。使用选项2的时间是,如果没有设置自动释放池(如果您在后台执行选择器,例如在+load中),但您应该尝试使用GCD。

总之,如果您没有很长的方法并且需要在自动释放池中包装循环,那么在大多数情况下请选择选项1。如果在没有设置自动释放池的情况下调用该方法,那么@autorelease必须是第一件事。