下面的代码在对象被取消初始化时(例如,在执行退回搜索到另一个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()
}
}
答案 0 :(得分:0)
此崩溃可能会造成混乱,并且如果尚未加载音序器的内容,也可能不会向控制台输出任何错误消息。非常无益!
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
}
}
希望这会有所帮助!