为什么我的 swift 应用 "leaking" 内存在 AVAsset 中

Why is my swift app "leaking" memory in AVAsset

从媒体文件中检索元数据时,我 运行 遇到了一个我无法解决的内存问题。

我想检索存储在本地应用程序存储或 iTunes 区域中的媒体文件的元数据。为此,我使用 AVAsset。在遍历这些文件时,我可以看到内存消耗不断上升。而且不只是一点点。当我在 phone.

上枚举我的 iTunes 库时,这很重要并最终导致应用程序停止运行

问题似乎是访问 AVAsset class 上的元数据 属性。我已经缩小到一行代码:'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 函数完成并且应用程序 returns 进入正常状态,所有内存将再次释放。

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

正如 post 评论中所建议的那样,解决方案是将特定代码包装在 'autoreleasepool' 块中。我已经用一小部分本地媒体文件和我相当大的 iTunes 媒体库 (70GB) 对此进行了测试。实施 'autoreleasepool' 后,内存堆积被消除。

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
  }
}