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

11

我有一个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(),它返回true。可能它能正常工作,但大约10到20分钟后就不能工作了。请注意,.play()现在返回false

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

  2. 也许我需要使用更低级别的API,例如OpenAL?但是我不会使用它,因为它在iOS 9中已被弃用,并且以后我将需要在没有OpenAL的情况下重新编写它。

  3. 还有更多的想法吗?也许我需要使用带有RemoteIOAudio Units?如果可以工作,请提供一些示例。

  4. 也许有第三方框架,例如ObjectAL - 它是OpenAL的易于实现版本。据我所知,它在iOS 9中可用。

这些方法只是我的猜测。但是主要问题仍然相同:这些方法能够在后台工作吗?


尝试过这个链接吗?https://dev59.com/_2cs5IYBdhLWcg3w5H5a - Penkey Suresh
它看起来不像一个答案。 - Nikita Zernov
禁用ARC:https://dev59.com/questions/T2w15IYBdhLWcg3wYawx - d4Rk
你尝试过这样做吗?你有解释吗? - Nikita Zernov
1个回答

2

你应该禁用ARC。当你进入后台时,如果你不使用它,它会被释放。在Swift中创建AVAudioPlayer时,将其作为Unmanaged<T>对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接