AVAudioSequencer 导致 Deinit/Segue 崩溃:"必需条件为假:输出节点"



每当取消初始化对象时(例如,在执行展开序列到另一个 ViewController 时(,下面的代码会导致崩溃并出现以下错误:

必需条件为 false: [AVAudioEngineGraph.mm:4474:GetDefaultMusicDevice: (outputNode(]

由于未捕获的异常"com.apple.coreaudio.avfaudio"而终止应用程序,原因:"必需条件为假:输出节点">

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

此崩溃可能会令人困惑,如果尚未加载排序器的内容,也可能不会向控制台输出任何错误消息。非常无益!

AVAudioSequencer确实是问题的原因。要修复它,请将 sequencer 设置为隐式解包的可选(即将!添加到其类型中(,并添加显式指令以在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
}
}

希望这有帮助!

最新更新