在 Swift 中,我注意到没有
@autoreleasepool{}
构造,尽管 Swift 确实使用了 ARC。在 Swift 中管理自动释放池的正确方法是什么,或者它是否因某种原因被删除?
语法如下:
autoreleasepool {
/* code */
}
不幸的是,Apple 的 WWDC 2014 视频似乎不再可用。万一它又回来了,WWDC 2014 年会议视频第 418 号“使用 Instruments 改进您的应用程序”中对此进行了介绍。
swift 文档 目前不包含任何有用的内容。但是您可以在 NSAutoreleasePool 的 Obj-C 运行时参考和高级内存管理编程指南下找到大量有用的信息。
注意: 自动释放池现在不再像过去那样重要。现代代码应该使用自动引用计数,它根本不使用释放池。然而,截至 2021 年,仍然有很多遗留代码(包括 Apple 的框架中的代码)使用自动释放池。作为一个示例,如果您正在对图像进行任何类型的批处理,您可能应该使用
autoreleasepool
块。
仅供参考,Xcode 构建的完整代码如下:
autoreleasepool({ () -> () in
// code
})
猜测括号标识了函数闭包。
有!只是没有在任何地方真正提到过。
autoreleasepool {
Do things....
}
我在我的代码中使用了这种结构。此功能是从视频 URL 创建缩略图。
func getThumbnailImage(forUrl url: URL) -> UIImage? {
return autoreleasepool{ () -> UIImage in
let asset: AVAsset = AVAsset(url: url)
let imageGenerator = AVAssetImageGenerator(asset: asset)
var thumbnailImage: CGImage?
do {
thumbnailImage = try imageGenerator.copyCGImage(at: CMTimeMake(value: 1, timescale: 60) , actualTime: nil)
return UIImage(cgImage: thumbnailImage!)
} catch let error {
print(error)
}
return UIImage(cgImage: thumbnailImage!)
}
}
所以需要做一系列的工作,每个部分都需要时间。我查看了上面的内容并在 Swift 中执行了此操作:
var quit = false
var blockDone = true
private var loops = 0
func main () {
repeat {
if blockDone {
blockDone = false
autoreleasepool {
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
print("dispatched")
blockDone = true
}
}
}
loops += 1
if !RunLoop.current.run(mode: .default, before: Date.distantFuture) {
print("break")
break
}
print("EXIT LOOP \(loops)")
} while !quit && loops < 10;
}
main()
仅执行调度就会导致运行循环旋转,从而产生
blockDone
标志。