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):
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!
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.
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
}
}
Hope this helps!