swift - 为什么我的 swift 应用程序在 AVAsset 中“泄漏”内存
问题描述
从媒体文件中检索元数据时,我遇到了一个我无法弄清楚的内存问题。
我想检索存储在本地应用程序存储或 iTunes 区域中的媒体文件的元数据。为此,我使用 AVAsset。在循环浏览这些文件时,我可以看到内存消耗不断上升。而不仅仅是一点点。当我在手机上枚举我的 iTunes 库时,这很重要,最终会导致应用程序停止运行。
问题似乎是访问 AVAsset 类的元数据属性。我已经缩小到一行代码:'let meta = ass.metadata'。拥有那行代码(没有任何引用)会使应用程序消耗内存。我已经包含了我的代码结构的示例。
func processFiles(_ files:Array)
{
var lastalbum : String = ""
var i : Int = 0
for file in files
{
i += 1
view.setProgressPosition(CGFloat(i)/CGFloat(files.count))
lastalbum = updateFile(file.url,lastalbum,
{ (album,title,artist,composer) in
view.setProgressNote(album,title,artist+" / "+composer)
})
}
}
func updateFile(_ url:URL,_ lastalbum:String,iPod:Bool=false,
_ progress:(String,String,String,String) -> Void) -> String
{
let ass = AVAsset(url:url)
let meta = ass.metadata
for item in meta
{
// Examine metadata
}
// Use metadata
// Callback with status
}
即使函数结束,似乎也会保留在 updateFile 方法中分配的内存。但是,一旦 processFile 函数完成并且应用程序恢复正常状态,所有内存都会再次释放。
所以总而言之,这不是真正的泄漏,但仍然是一个重大问题。关于哪里出了问题有什么好主意吗?有什么办法可以强制内存管理运行清理?
解决方案
正如帖子评论中所建议的那样,解决方案是将特定代码包装在“autoreleasepool”块中。我已经用一小组本地媒体文件和我相当大的 iTunes 媒体库 (70GB) 对此进行了测试。实施“自动释放池”后,内存积累被消除。
func updateFile(_ url:URL,_ lastalbum:String,iPod:Bool=false,
_ progress:(String,String,String,String) -> Void) -> String
{
autoreleasepool
{
let ass = AVAsset(url:url)
let meta = ass.metadata
for item in meta
{
// Examine metadata
}
// Use metadata
// Callback with status
}
}
推荐阅读
- dockerfile - 如何在 docker 中加载 libftdi.so.1 共享对象
- java - Akka testkit 类型不编译
- multithreading - 为什么 EventDispatcher 被阻止
- kirby - 为什么我无法连接到我的本地 Kirby API?
- python - 使用密码学的 python 守护程序的 pyinstaller 抛出异常:'没有名为 '_hmacopenssl' 的模块
- arrays - 二分查找复杂度分析(不均匀拆分)
- artifactory - 我可以对现有的 Artifactory 访问令牌执行查询以了解它是如何创建的吗?
- python - Python中的插值要快得多?
- mariadb - 发送数据库邮件
- flutter - 单击其中任何一个时展开/折叠多个 ExpansionTile