是否有必要在 Swift 程序中使用 autoreleasepool? [英] Is it necessary to use autoreleasepool in a Swift program?

查看:25
本文介绍了是否有必要在 Swift 程序中使用 autoreleasepool?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个 WWDC14 演示文稿的第 17 页上,它说

<块引用>

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

这是什么意思?这是否意味着如果我的代码库没有任何 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);}}}}

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

解决方案

autoreleasepool 模式在 Swift 中用于返回 autorelease 对象(由您的 Objective-C 创建代码或使用 Cocoa 类).Swift 中的 autorelease 模式与 Objective-C 中的功能非常相似.例如,考虑你的方法的这个 Swift 版本(实例化 NSImage/UIImage 对象):

func useManyImages() {让文件名 = pathForResourceInBundle对于 _ 在 0 ..<5{自动释放池{对于 _ 在 0 ..<1000 {让图像 = NSImage(contentsOfFile: 文件名)}}}}

如果你在 Instruments 中运行它,你会看到一个带有 5 小山丘的分配图(因为外部 for 循环),如下所示:

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

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

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

On page 17 of this WWDC14 presentation, it says

Working with Objective-C? Still have to manage autorelease pools
autoreleasepool { /* code */ }

What does that mean? Does it mean that if my code base doesn't have any Objective-C files, autoreleasepool {} is unnecessary?

In an answer of a related question, there is an example where autoreleasepool can be useful:

- (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);
            }
        }
    }
}

If the code above gets translated into Swift with autoreleasepool dropped, will Swift be smart enough to know that the number variable should be released after the first } (like some other languages does)?

解决方案

The autoreleasepool pattern is used in Swift when returning autorelease objects (created by either your Objective-C code or using Cocoa classes). The autorelease pattern in Swift functions much like it does in Objective-C. For example, consider this Swift rendition of your method (instantiating NSImage/UIImage objects):

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

If you run this in Instruments, you'll see an allocations graph with 5 small hills (because outer for-loop), like the following:

But if you do it without the autorelease pool, you'll see that peak memory usage is higher:

The autoreleasepool allows you to explicitly manage when autorelease objects are deallocated in Swift, just like you were able to in Objective-C.

Note: When dealing with Swift native objects, you generally will not receive autorelease objects. This is why the presentation mentioned the caveat about only needing this when "working with Objective-C", though I wish Apple was more clear on this point. But if you're dealing with Objective-C objects (including Cocoa classes), they may be autorelease objects, in which case this Swift rendition of the Objective-C @autoreleasepool pattern is still useful.

这篇关于是否有必要在 Swift 程序中使用 autoreleasepool?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆