是否有必要在Swift程序中使用autoreleasepool?

时间:2014-09-16 04:55:52

标签: memory-management swift

this WWDC14 presentation的第17页,它说

  

使用Objective-C?仍然需要管理自动释放池
  autoreleasepool {/ * code * /}

这是什么意思?这是否意味着如果我的代码库没有任何Objective-C文件,那么autoreleasepool {}是不必要的?

an answer of a related question中,有一个autoreleasepool可能有用的示例:

- (void)useALoadOfNumbers {
    for (int j = 0; j < 10000; ++j) {
        @autoreleasepool {
            for (int i = 0; i < 10000; ++i) {
                NSNumber *number = [NSNumber numberWithInt:(i+j)];
                NSLog(@"number = %p", number);
            }
        }
    }
}

如果将上面的代码转换为Swift并删除了autoreleasepool,那么Swift会非常聪明地知道number变量应该在第一个}之后发布(就像其他一些语言一样)一样)?

3 个答案:

答案 0 :(得分:166)

在返回autoreleasepool对象(由Objective-C代码或使用Cocoa类创建)时,在Swift中使用autorelease模式。 Swift中的autorelease模式与Objective-C中的模式非常相似。例如,考虑你的方法的Swift再现(实例化NSImage / UIImage对象):

func useManyImages() {
    let filename = pathForResourceInBundle

    for _ in 0 ..< 5 {
        autoreleasepool {
            for _ in 0 ..< 1000 {
                let image = NSImage(contentsOfFile: filename)
            }
        }
    }
}

如果您在Instruments中运行此功能,您将看到如下所示的分配图:

with autoreleasepool

但是如果你在没有自动释放池的情况下这样做,你会发现峰值内存使用量更高:

without autoreleasepool

autoreleasepool允许您显式管理何时在Swift中释放自动释放对象,就像您在Objective-C中一样。

注意:处理Swift本机对象时,通常不会收到自动释放对象。这就是为什么演示文稿提到了在“使用Objective-C”时只需要这个的警告,尽管我希望Apple在这一点上更清楚。但是如果您正在处理Objective-C对象(包括Cocoa类),它们可能是自动释放对象,在这种情况下,Swift对Objective-C @autoreleasepool模式的再现仍然有用。

答案 1 :(得分:4)

如果你在等效的Objective-C代码中使用它,那么你可以在Swift中使用它。

  

将Swift足够聪明地知道数字变量应该是   在第一个}

之后发布

仅在Objective-C的情况下。两者都遵循Cocoa内存管理规则。

当然ARC知道number在循环迭代结束时超出范围,如果保留它,它将在那里释放它。但是,这并不能告诉您对象是否已自动释放,因为-[NSNumber numberWithInt:] 可能会或可能不会返回自动释放的实例。您无法知道,因为您无法访问-[NSNumber numberWithInt:]的来源。

答案 2 :(得分:0)

@autoreleasepool 可以在 Objective-C 和 Swift 代码中使用,以保证使用依赖于 autorelease

的 Objective-C 代码

[Under the hood]