【问题标题】:AVAudioSequencer Causes Crash on Deinit/Segue: 'required condition is false: outputNode'AVAudioSequencer 导致 Deinit/Segue 崩溃:'必需条件为 false:outputNode'
【发布时间】:2020-01-21 23:28:54
【问题描述】:

每当对象被取消初始化时(例如,当执行展开转回另一个 ViewController 时),以下代码会导致崩溃并出现以下错误:

要求条件为假:[AVAudioEngineGraph.mm:4474:GetDefaultMusicDevice: (outputNode)]

由于未捕获的异常“com.apple.coreaudio.avfaudio”而终止应用程序,原因:“所需条件为假:outputNode”

AVAudioSequencer 是问题的根源,因为如果删除它,错误就会停止。

如何避免这种崩溃?

class TestAudioClass {
    
    private var audioEngine: AVAudioEngine
    private var sampler: AVAudioUnitSampler
    private var sequencer: AVAudioSequencer
    
    init() {
        self.audioEngine = AVAudioEngine()
        self.sampler = AVAudioUnitSampler()
        audioEngine.attach(sampler)
        audioEngine.connect(sampler, to: audioEngine.mainMixerNode, format: nil)
        self.sequencer = AVAudioSequencer(audioEngine: audioEngine)
        if let fileURL = Bundle.main.url(forResource: "TestMusic", withExtension: "mid") {
            do {
                try sequencer.load(from: fileURL, options: AVMusicSequenceLoadOptions())
            } catch {
                print("Error loading sequencer: \(error.localizedDescription)")
            }
        }
        sequencer.prepareToPlay()
    }
}

【问题讨论】:

    标签: ios swift avfoundation core-audio avaudioengine


    【解决方案1】:

    此崩溃可能会造成混淆,并且如果尚未加载定序器的内容,也可能不会向控制台输出任何错误消息。非常无用!

    AVAudioSequencer 确实是问题的原因。要修复它,使序列器成为隐式解包的可选(即添加! 到它的类型)并添加显式指令以在deinit 期间停止和删除它,之前对象的其余部分被取消初始化.

    固定代码如下(特别注意deinit方法):

    class TestAudioClass {
    
        private var audioEngine: AVAudioEngine
        private var sampler: AVAudioUnitSampler
        private var sequencer: AVAudioSequencer!
    
        init() {
            self.audioEngine = AVAudioEngine()
            self.sampler = AVAudioUnitSampler()
            audioEngine.attach(sampler)
            audioEngine.connect(sampler, to: audioEngine.mainMixerNode, format: nil)
            self.sequencer = AVAudioSequencer(audioEngine: audioEngine)
            if let fileURL = Bundle.main.url(forResource: "TestMusic", withExtension: "mid") {
                do {
                    try sequencer.load(from: fileURL, options: AVMusicSequenceLoadOptions())
                } catch {
                    print("Error loading sequencer: \(error.localizedDescription)")
                }
            }
            sequencer.prepareToPlay()
        }
    
        deinit {
            sequencer.stop()
            sequencer = nil
        }
    }
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-23
      • 2020-12-02
      • 2013-11-11
      相关资源
      最近更新 更多