我目前正在开发一个基于图像/对象状态播放音频剪辑的应用。
当前我收到此错误代码。
线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x48)
我想如果已经在同一线程上播放了另一个音频剪辑,则尝试在同一线程上播放另一个音频剪辑可能会出错。
但是说实话,我不确定,我仍在学习有关线程和多线程的知识,所以我很可能到达这里。
我在这里想念什么?我如何才能播放第二个音频剪辑(turnSaberOffAudio),而不会收到此错误消息?谢谢!
这是我点击按钮时发生的情况。
@objc func lightsaberTapped() {
print("lightsaber open!")
if lightsaberModel.isSaberOn == false {
UIView.animate(withDuration: 0.2, animations: {
self.saberImageHeightConstraint.constant = 530
self.saberImageWidthConstraint.constant = 210
self.mainView.layoutIfNeeded()
self.viewDidLayoutSubviews()
}, completion: nil)
lightsaberModel.turnSaberOnAudio.play()
lightsaberModel.isSaberOn = true
} else {
UIView.animate(withDuration: 0.2, animations: {
self.saberImageHeightConstraint.constant = 1
self.saberImageWidthConstraint.constant = 1
self.mainView.layoutIfNeeded()
self.viewDidLayoutSubviews()
}, completion: nil)
lightsaberModel.turnSaberOffAudio.play()
lightsaberModel.isSaberOn = false
}
}
这是带有必要信息的模型。
class Model {
var turnSaberOnAudio: AVAudioPlayer = AVAudioPlayer()
var turnSaberOffAudio: AVAudioPlayer = AVAudioPlayer()
var whichLightsaber = String()
var isSaberOn = Bool()
func turnSaberOn() {
let turnSaberOnPath = Bundle.main.path(forResource: "SaberOn", ofType: "wav")
do {
turnSaberOnAudio = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: turnSaberOnPath!))
}
catch {
print(error)
}
}
func turnSaberOff() {
let turnSaberOffPath = Bundle.main.path(forResource: "SaberOff", ofType: "mp3")
do {
turnSaberOffAudio = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: turnSaberOffPath!))
}
catch {
print(error)
}
}
}
答案 0 :(得分:0)
这是你永远不应该做的事情:
var turnSaberOnAudio: AVAudioPlayer = AVAudioPlayer()
空的初始化程序AVAudioPlayer()
会产生一些无用的东西,这不仅是无用的,而且还会导致崩溃。
并且将var声明为非可选,则无法区分它是否包含有用的内容。
使用您当前的代码,调用turnSaberOn()
时可能不会调用turnSaberOff()
或play()
。
尝试将您的Model
更改为:
class Model {
var turnSaberOnAudio: AVAudioPlayer? //<- Never use `AVAudioPlayer()`
var turnSaberOffAudio: AVAudioPlayer? //<- Never use `AVAudioPlayer()`
var whichLightsaber: String = ""
var isSaberOn: Bool = false
init() {
let turnSaberOnUrl = Bundle.main.url(forResource: "SaberOn", withExtension: "wav")!
do {
turnSaberOnAudio = try AVAudioPlayer(contentsOf: turnSaberOnUrl)
turnSaberOnAudio!.prepareToPlay()
print("\(turnSaberOnUrl) loaded")
} catch {
print(error)
}
let turnSaberOffUrl = Bundle.main.url(forResource: "SaberOff", withExtension: "mp3")!
do {
turnSaberOffAudio = try AVAudioPlayer(contentsOf: turnSaberOffUrl)
turnSaberOffAudio!.prepareToPlay()
print("\(turnSaberOffUrl) loaded")
} catch {
print(error)
}
//...
}
//...
}
并像这样使用它:
@IBAction func lightSaberTapped(_ sender: Any) {
print("lightsaber open!")
if !lightsaberModel.isSaberOn {
//...
lightsaberModel.turnSaberOnAudio?.play()
lightsaberModel.isSaberOn = true
} else {
//...
lightsaberModel.turnSaberOffAudio?.play()
lightsaberModel.isSaberOn = false
}
}