2012-04-12 73 views
21

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

1:

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

2:

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

哪个更好?或代码1和2之间的任何区别?

谢谢!

+0

循环应该在autoreleasepool内部 2.是正确的 – Charan 2012-04-12 10:03:13

+0

看看[Objective C/Cocoa/iPhone的内存管理](http://memo.tv/archive/memory_management_with_objective_c_cocoa_iphone)。 – 2012-04-12 10:40:46

回答

28

在你的第一个例子中,每次迭代池都被排空。如果迭代的主体涉及很多自动释放对象,这是有意义的。

第二个示例只会在循环之后耗尽一次池。

因此,如果循环的内部导致内存膨胀,然后去选项一。如果整个循环的内存膨胀是可接受的,则循环然后使用选项二。

1

我会去版本2

一个@autoreleasepool块将释放当块结束收到一个autorelease所有对象。这需要时间,因为它需要一些cpu周期,并且根据对象的不同,使用时间可能会高于预期。

我认为自定义@autoreleasepool只有在处理大于20MB的数据或在非主线程中使用Data时才有意义。

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

+0

我不明白,发布的总CPU周期是相同的,因为最终发布的总体对象是相同的。你在谈论执行autorelease池检查的开销吗?我不确定那里的开销。 – 2015-09-10 20:24:58

+0

@HelinWang耗尽内存往往意味着浪费NSAutoreleasePool上的CPU周期。 – Andy 2015-11-05 09:08:49

+0

@Andy这就是我的评论问:为什么它会耗尽太多的记忆? ---“最终发布的对象总是相同的” – 2015-11-05 20:20:32

3

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

0

取决于有多少待处理项目将被释放。形象,Autorelease池像垃圾一样,把未使用的东西,并会在稍后投掷。

0

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

你一般不需要自动释放池,如果你这样做,因为你是在一个循环中,并自动释放大量的对象,然后选择1,使超过2个意义,因为你正试图避免秒杀环路是创建。使用选项2的时间是如果没有设置自动释放池(如果您在后台执行选择器,例如或在+load中),但您应该真的尝试为这些使用GCD。

总之,如果你没有一个很长的方法,你需要换一个自动释放池循环,走在大多数情况下选择1。如果在没有设置自动释放池的情况下调用方法,则需要首先将@autorelease