我是Objective-C的新手,我不确定我是否正确使用NSAutoreleasePool。
如果我只想使用一次自动释放:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *newText = [NSString stringWithFormat:@"%d", prograssAsInt];
sliderLabel.text = newText;
[pool release]; //newText will be released
如果我想多次使用autorelease,我会使用:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *newText = [NSString stringWithFormat:@"%d", prograssAsInt];
sliderLabel.text = newText;
[pool drain]; //newText will be released
newText = [NSString stringWithFormat:@"%d", prograssAsInt];
sliderLabel.text = newText;
[pool drain]; //newText will be released
newText = [NSString stringWithFormat:@"%d", prograssAsInt];
sliderLabel.text = newText;
[pool release]; //newText will be released
这样好吗?有没有内存泄漏?
答案 0 :(得分:3)
我想说调用[pool drain]
是不必要的。我从来没有见过它们在实践中使用过。我想如果你在自动释放池中分配大量内存,可能是必要的。但在典型的情况下,我认为不会。
顺便说一句,您将希望开始使用以下构造用于自动释放池:
@autoreleasepool {
... your code ...
}
这显然比“旧”方式(你的方式)更有效率。在功能上,它是相同的,但在内部它表现得更好。最近的Xcode / iOS发行说明中有一些相关内容。
答案 1 :(得分:3)
很抱歉这样说,但RTFM。在调用-drain
之后,池将自行释放,因此它无效。
目前,在使用Apple的LLVM编译器的objective-c中,有一个名为@autoreleasepool
的语言添加,可以同时使用ARC和非ARC代码,您可以这样使用:
@autoreleasepool {
// code that will automatically have any -autoreleased variables cleaned up.
}
答案 2 :(得分:3)
(2)不行。 -drain
和-release
是等效的(在引用计数环境中),并且在-drain
后自动释放池被释放。因此,您将双重释放自动释放池对象并使程序崩溃。
即使在ARC之前,除非你在非常严格的内存预算中工作,否则在样板main()
之外创建一个NSAutoreleasePool是不典型的。无论如何,进入池中的对象-autorelease
将在NSRunLoop的每个滴答之后释放。如果严格遵守所有权转移规则,则不会发生内存泄漏(请参阅Understanding reference counting with Cocoa and Objective-C)。
启用了 ARC,您甚至不需要关心这一点 - 编译器会在适当的位置插入-retain
和-release
。< / p>
此外,如果sliderLabel.text
被标记为@property(retain)
(或(strong)
),则释放(1)中的自动释放池将不会释放newText,因为该对象现在拥有新的所有者
答案 3 :(得分:3)
通常情况下,如果您在主线程上并且没有使用大量资源密集型代码,则无需创建自己的自动释放池。只需使用为您创建的默认值。
如果你是多线程的,或者你正在做一个内存密集的长时间循环(你可能不应该在主线程上做),你只需要创建自己的循环。