AVAudioSequencer 在 Deinit/Segue 上导致崩溃:'required condition is false: outputNode'
AVAudioSequencer Causes Crash on Deinit/Segue: 'required condition is false: outputNode'
每当对象被取消初始化时(例如,当执行展开转场回到另一个 ViewController 时),以下代码会导致崩溃并出现以下错误:
required condition is false: [AVAudioEngineGraph.mm:4474:GetDefaultMusicDevice: (outputNode)]
Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: 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()
}
}
此崩溃可能会令人困惑,并且如果尚未加载音序器的内容,也可能不会向控制台输出任何错误消息。非常无用!
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
}
}
希望对您有所帮助!
每当对象被取消初始化时(例如,当执行展开转场回到另一个 ViewController 时),以下代码会导致崩溃并出现以下错误:
required condition is false: [AVAudioEngineGraph.mm:4474:GetDefaultMusicDevice: (outputNode)]
Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: 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()
}
}
此崩溃可能会令人困惑,并且如果尚未加载音序器的内容,也可能不会向控制台输出任何错误消息。非常无用!
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
}
}
希望对您有所帮助!