AVAudioPlayer预装了内存中的声音泄漏

时间:2015-07-03 18:44:49

标签: ios memory-management memory-leaks background avaudioplayer

我有一个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(自动引用计数)以手动释放和释放audioPlayer

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

  3. 还有什么想法吗?也许我需要Audio Units使用RemoteIO?如果有效,请提供一些例子。

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

  5. 这些方法只是我的假设。但他们的主要问题仍然是相同的:这些方法是否可以在后台运作?

1 个答案:

答案 0 :(得分:2)

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