Memory management 是否有必要在Swift程序中使用自动释放池?

Memory management 是否有必要在Swift程序中使用自动释放池?,memory-management,swift,Memory Management,Swift,在第17页,它说 与Objective-C合作?仍然必须管理自动释放池 自动释放池{/*代码*/} 这是什么意思?这是否意味着如果我的代码库没有任何Objective-C文件,autoreleasepool{}是不必要的 在中,有一个示例,autoreleasepool非常有用: - (void)useALoadOfNumbers { for (int j = 0; j < 10000; ++j) { @autoreleasepool { f

在第17页,它说

与Objective-C合作?仍然必须管理自动释放池
自动释放池{/*代码*/}

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

在中,有一个示例,
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);
            }
        }
    }
}
—(无效)UseAloadOfNumber{
对于(int j=0;j<10000;++j){
@自动释放池{
对于(int i=0;i<10000;++i){
NSNumber*number=[NSNumber number WITHENT:(i+j)];
NSLog(@“编号=%p”,编号);
}
}
}
}

如果上面的代码被翻译成Swift,并且删除了
autoreleasepool
,Swift是否足够聪明,知道
number
变量应该在第一个
}
之后释放(就像其他一些语言一样)?

如果您要在等效的Objective-C代码中使用它,那么您将在Swift中使用它

斯威夫特会聪明到知道数字变量应该是 在第一次之后发布}

只有当Objective-C完成时。两者都按照Cocoa内存管理规则进行操作


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

的源代码,在返回
自动释放
对象(由您的Objective-C代码或使用Cocoa类创建)时,Swift中会使用
自动释放池
模式。SWIFT函数中的<代码>自动代码< /COD>模式非常类似于Objto- C。例如,考虑您的方法的快速转换(实例化<代码> NSImage <代码> />代码> UIImage < /Cord>对象):

func useManyImages(){
让filename=pathForResourceInBundle
对于0..<5中的uu{
自动释放池{
对于0中的uu..<1000{
让image=NSImage(contentsOfFile:filename)
}
}
}
}
如果在Instruments中运行此操作,您将看到如下分配图:

但如果您在没有自动释放池的情况下执行此操作,您将看到峰值内存使用率更高:


autoreleasepool
允许您显式管理在Swift中释放autorelease对象的时间,就像您在Objective-C中一样


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

@autoreleasepool
可以在Objective-C和Swift代码中使用,以确保使用依赖于
自动释放的Objective-C代码


在Swift中,似乎没有关于
autoreleasepool
的文档。I.如果Swift在这方面的行为与Objective-C相同,那么为什么演示文稿会特别提到“使用Objective-C?”@Ethan看来,本机Swift对象不是自动释放对象,而
autoreleasepool
构造完全没有必要。但是,如果您的Swift代码正在处理Objective-C对象(包括Cocoa对象),那么这些对象确实遵循自动释放模式,因此,
autoreleasepool
构造变得很有用。我知道“autoreleasepool允许您显式管理在Swift中释放自动释放对象的时间”,但我为什么要这样做呢?为什么编译器不能为我做这件事?我不得不添加我自己的自动释放池,以防止VM在一个巨大的字符串操作的紧密循环中崩溃。这对我来说是显而易见的,它应该被添加到哪里,并且它工作得非常完美。为什么编译器不能这样做?编译器是否可以更智能地完成这项工作?在所有这些问题上,您可以编写自己的类,并让它在
deinit
中执行
println
,并且在解除分配对象时可以非常容易地精确验证。或者用仪器观察。在回答您的问题时,Swift对象似乎是从保留计数为+1的函数返回的(不是自动释放对象),调用方将从该点无缝地管理所有权(例如,如果返回的对象超出范围,它将立即被释放,而不是放在自动释放池中)@StevenHernandez一个自动释放池与泄漏几乎没有关系。泄漏是由未释放的对象引起的。另一方面,Autorelease池只是一个对象集合,其释放被推迟到池耗尽为止。池不控制是否释放某些内容,而只是控制此类释放的时间。重新映射视图时,您无法控制缓存的功能(使用内存,但不是真正的泄漏),如果存在真正的泄漏,您也无法执行任何操作(我不知道有任何重大的映射视图泄漏,尽管历史上UIKit中存在随机、适度的泄漏)。@matt Yeah,我看到了类似的行为。因此,我用
NSImage
/
UIImage
对象重复了我的练习,并更加一致地说明了这个问题(坦率地说,这是一个更常见的问题示例,因为峰值内存使用通常只会在处理较大对象时出现问题;这方面的一个实际示例可能是一个调整一组图像大小的例程)。我还复制了调用Objective-C代码的行为
func useManyImages() {
    let filename = pathForResourceInBundle

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