【问题标题】:AVAudioPlayer causing app to crashAVAudioPlayer 导致应用程序崩溃
【发布时间】:2018-05-18 20:48:51
【问题描述】:

我正在开发一个应用程序,该应用程序每 200 毫秒接收一个整数,并将在接下来的 200 毫秒间隔内均匀分布整数的大小播放音调。声音工作正常,但应用程序在完全随机的时间崩溃。我最初是在 ipod(第 5 代)上进行测试,它在 1 分钟到 10 分钟之间的任何地方崩溃,给我一个错误

“EXC_BREAKPOINT (EXC_ARM_BREAKPOINT, subcode=0xdefe)”

在我得到EXC_BAD_ACCESS 之前,但在将播放器定义移动到AppDelegate 以及其他尝试修复之后,消息现在是ARM 断点之一。我还尝试了我的 iPhone 6S+,它运行了超过 15 分钟,没有崩溃。

播放器是在 ViewController 中定义的(正如这里的另一篇文章所建议的那样),如下所示:

var audioPlayer: AVAudioPlayer!

这是一个视图控制器类中用于播放音调的代码:

//called for every beep
@objc func playSound() {
    toneCount += 1
    if toneCount >= totalTones{
        if toneTimer != nil {
            toneTimer?.invalidate()
            toneTimer = nil
        }
    }
    do{
        guard let url = Bundle.main.url(forResource: "geiger", withExtension: "mp3") else { return }
        audioPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)
        audioPlayer.play()
    }catch{
        print("failed")
    }

}

这是崩溃发生时向控制台的输出:

"[AVAudioPlayer performSelector:withObject:]: message sent to deallocated instance 0x1886b590"

在堆栈帧中(不确定这是否是正确的术语,但控制台输出左侧的帧)播放器变量显示它等于(AVAudioPlayer)?在 player 变量中是 "ObjectiveC.NSObject",它本身是空的

真的不太确定还能尝试什么,因为我尝试让 player 成为一个弱变量,但随后音调无法播放。我试过在视图控制器中定义它。这也让我感到困惑,为什么它似乎没有在 iphone 6S+ 上崩溃,以及为什么崩溃发生的时间是完全随机的。

我也尝试在单独的文件中创建一个单例类,如下所示:

let tone = soundtest()

class soundtest {
    func playTone() {
        do{
            print("played Sound")
            guard let url = Bundle.main.url(forResource: "geiger", withExtension: "mp3") else { return }
            let audioPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)
            audioPlayer.play()
        }catch{
            print("failed")
        }
    }
}

尝试播放音调的声音如下:

tone.playTone()

现在声音不播放了

【问题讨论】:

  • 你能澄清一下,你说player是在AppDelegate中定义的,playSound是在viewController中定义的。怎么直接得到playSound中的player变量?
  • 我使用播放器作为全局变量,另一篇文章建议这样做。但无论如何我认为我已经解决了这个问题,我将播放器定义为“var audioPlayer: AVAudioPlayer?”在 ViewController 类中,然后在 playSound 函数中,我现在将播放器声明为“self.audioPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)”。如果它在 15 分钟内没有崩溃,我将添加作为解决方案。如果失败了,你有什么其他想法
  • guard let url = Bundle.main.url(forResource: "geiger", withExtension: "mp3") else { return } self.audioPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3 .rawValue) 尝试 AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback) 尝试 AVAudioSession.sharedInstance().setActive(true) if self.audioPlayer != nil{ self.audioPlayer?.play() }else{ print("player was nil ") }
  • 我现在在 playSound 函数的 do 语句中拥有这个,并且我从 appDelegate 中删除了定义。 5 分钟后仍然崩溃
  • ipod 可能在旧版本上再次抛出错误。它现在已经运行了 10 多分钟,所以上述更改可能已经修复。

标签: ios swift xcode avplayer avaudioplayer


【解决方案1】:

很可能发生崩溃是因为audioPlayer 在声音结束之前被释放。为防止这种情况,正如您在评论中所写,您可以在致电playSound 之前检查播放器是否正在播放声音。或者将每个player 存储在数组中,然后在声音结束时释放。

【讨论】:

  • 谢谢!我会记住这一点,现在我会在播放下一个声音之前停止声音,但我认为这意味着如果声音播放得非常快,那么它们可能会在完成之前被切断,甚至可能根本不播放。截至目前,我将保留它,因为它不再崩溃,但一旦我可以更专注于此,我将使用您的建议进行调查!
  • @Mumphus,当然,那么您可以关闭问题。祝你今天过得愉快! :)
猜你喜欢
  • 1970-01-01
  • 2015-10-21
  • 2016-06-04
  • 2011-08-24
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
相关资源
最近更新 更多