首页 > 解决方案 > 为什么我的 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 函数完成并且应用程序恢复正常状态,所有内存都会再次释放。

所以总而言之,这不是真正的泄漏,但仍然是一个重大问题。关于哪里出了问题有什么好主意吗?有什么办法可以强制内存管理运行清理?

标签: swiftavasset

解决方案


正如帖子评论中所建议的那样,解决方案是将特定代码包装在“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
  }
}

推荐阅读