AVAudioPlayer 预加载的声音从内存中泄漏

AVAudioPlayer preloaded sound leaks from memory

我有一个 AVAudioPlayer 实例,它使用 audioPlayer.prepareToPlay() 将声音加载到内存中,然后在几次之后开始播放它。我有一个问题,进入后台后大约十分钟,它从内存中泄漏,我没有做好准备。在那个喂食时间之后,我没有能力再次 运行 prepareToPlay()。如何将预加载的声音长期留在内存中?我正在准备在 applicationDidFinishLaunchingWithOptions 方法中播放的声音:

let dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
    dispatch_async(dispatchQueue, {[weak self] in
        var audioSessionError: NSError?

        let audioSession = AVAudioSession.sharedInstance()
        NSNotificationCenter.defaultCenter().addObserver(self!, selector: "handleInterruption:", name: AVAudioSessionInterruptionNotification, object: nil)
        audioSession.setActive(true, error: nil)

        if (audioSession.setCategory(AVAudioSessionCategoryPlayback, error: &audioSessionError)) {
            println("Successfully set the audio session")
        } else {
            println("Could not set the audio session")
        }

        let filePath = NSBundle.mainBundle().pathForResource("sound", ofType:"mp3")
        let fileData = NSData(contentsOfFile: filePath!, options: .DataReadingMappedIfSafe, error: nil)
        var error:NSError?

        self!.audioPlayer = AVAudioPlayer(data: fileData, error: &error)

        self!.audioPlayer?.numberOfLoops = -1

        self!.audioPlayer?.delegate = self

        if (self?.audioPlayer?.prepareToPlay() != false) {
            println("Successfully prepared for playing")
        } else {
            println("Failed to prepare for playing")
        }
    })

然后在 didReceiveRemoteNotification 我试图在后台播放它:self.audioPlayer?.play(),它 returns true。可能它有效,但在大约 10 - 20 分钟后它不起作用。并注意 .play() 现在 returns false.

  1. 禁用ARC(自动引用计数)以手动释放和释放audioPlayer是否有意义?

  2. 也许我需要使用较低级别的 API,例如 OpenAL?但是我不会使用它,因为它在 iOS 9 中已被弃用,以后我将需要在没有 OpenAL.

  3. 的情况下重写它
  4. 还有什么想法吗?也许我需要将 Audio UnitsRemoteIO 一起使用?如果可行,请提供一些示例。

  5. 也许有像 ObjectAL 这样的第三方框架 - OpenAL 的简单实现。据我所知,它在 iOS 9.

  6. 中可用

这些方法只是我的假设。但他们的主要问题保持不变:这些方法会在后台运行吗?

您应该只禁用 ARC。当你进入背景时,如果你不使用它,它就会被释放。在 Swift 中创建 AVAudioPlayer 作为 Unmanaged<T> 对象。