AVAudioSequencer导致Deinit/Segue崩溃:“所需条件为假:outputNode" [英] AVAudioSequencer Causes Crash on Deinit/Segue: 'required condition is false: outputNode'

查看:86
本文介绍了AVAudioSequencer导致Deinit/Segue崩溃:“所需条件为假:outputNode"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当取消初始化对象时(例如,在执行退回搜索到另一个ViewController时),以下代码都会导致崩溃,并显示以下错误:

The below code causes a crash with the following errors whenever the object is deinitialized (e.g. when performing an unwind segue back to another ViewController):

所需条件为假:[AVAudioEngineGraph.mm:4474:GetDefaultMusicDevice:(outputNode)]

required condition is false: [AVAudioEngineGraph.mm:4474:GetDefaultMusicDevice: (outputNode)]

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

Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: outputNode'

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

The AVAudioSequencer is the root of the issue, because the error ceases if this is removed.

如何避免这种崩溃?

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()
    }
}

推荐答案

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

This crash can be confusing, and may also output no error message whatsoever to the console if the sequencer's content hasn't been loaded yet. Very unhelpful!

AVAudioSequencer确实是问题的原因.要解决此问题,请使音序器成为隐式展开的可选内容(即,将!添加到其类型中),并添加明确的指令以停止&在deinit之前期间将其删除,其余对象将被取消初始化.

The AVAudioSequencer is indeed the cause of the issue. To fix it, make the sequencer an implicitly unwrapped optional (i.e. add ! to its type) and add explicit instructions to stop & remove it during deinit, before the rest of the object is deinitialized.

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

The fixed code is as follows (take note of the deinit method especially):

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
    }
}

希望这会有所帮助!

这篇关于AVAudioSequencer导致Deinit/Segue崩溃:“所需条件为假:outputNode"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆