1

我是 Objective-C 的新手,我不确定我是否以正确的方式使用 NSAutoreleasePool。

  1. 如果我只想使用一次自动释放,我使用:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *newText = [NSString stringWithFormat:@"%d", prograssAsInt];
    sliderLabel.text = newText;
    [pool release]; //newText will be released
    
  2. 如果我想多次使用自动释放,我使用:

    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
    

这个可以吗?有内存泄漏吗?

4

4 回答 4

3

通常,如果您在主线程上并且没有使用大量资源密集型代码循环,那么您永远不需要创建自己的自动释放池。只需使用为您创建的默认设置。

如果你是多线程或者你正在做一个内存密集型长时间运行的循环(你可能不应该在主线程上做),你只需要自己做。

于 2012-05-01T16:12:36.670 回答
3

我会说调用[pool drain]是不必要的。我从未见过它们在实践中使用过。我想如果你在自动释放池中分配大量内存,这可能是必要的。但在典型情况下,我认为不会。

顺便说一下,您将希望开始使用以下构造来用于自动释放池:

@autoreleasepool {
    ... your code ...
}

显然,这比“旧”方式(你正在做的方式)更有效。从功能上讲,它是相同的,但在内部它的性能要好得多。在最近的 Xcode/iOS 发行说明中有一些关于此的内容。

于 2012-05-01T15:54:36.177 回答
3

很抱歉这么说,但是RTFM。调用后-drain,池会自行释放,使其无效。

而且,目前,在带有 Apple 的 LLVM 编译器的 Objective-c 中,有一个名为的语言添加@autoreleasepool,它适用于 ARC 和非 ARC 代码,您可以这样利用:

@autoreleasepool {
    // code that will automatically have any -autoreleased variables cleaned up.
} 
于 2012-05-01T15:55:49.893 回答
3

(2) 不行。-drain并且-release是等效的(在引用计数环境中),并且-drain在自动释放池被释放之后。因此,您将双重释放自动释放池对象并使程序崩溃。

即使在 ARC 之前,除非您的内存预算非常紧张,否则在样板文件之外创建 NSAutoreleasePool 是不典型的main()-autorelease无论如何,在每次 NSRunLoop 滴答之后,对象d 都会被释放到池中。如果您严格遵守所有权转移规则,则不会发生内存泄漏(请参阅使用 Cocoa 和 Objective-C 了解引用计数)。

启用 ARC后您甚至不需要关心这一点 — 编译器会在正确的位置插入-retain-release


此外,如果sliderLabel.text标记为@property(retain)(或(strong)),则在 (1) 中释放自动释放池将不会释放 newText,因为该对象现在有了新所有者。

于 2012-05-01T15:57:40.143 回答