我收到以下错误消息,无法弄清楚我做错了什么。这是我的第一个程序,对如何调试它并不太了解。
错误讯息:
致命错误:在展开Optional值时意外发现nil (lldb)
代码:
import UIKit
import AVFoundation
class PlaySoundsViewController: UIViewController {
var audioPlayer:AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if var filePath = NSBundle.mainBundle().pathForResource("crankringtone", ofType: "mp3"){
var filePathUrl = NSURL.fileURLWithPath(filePath)
audioPlayer = AVAudioPlayer(contentsOfURL: filePathUrl, error: nil)
} else {
println("file path is empty")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func playSlowAudio(sender: UIButton) {
audioPlayer.stop()
}
}
答案 0 :(得分:0)
在使用之前,您需要检查filePathUrl
的值是否为非零值。
答案 1 :(得分:0)
NSURL.fileURLWithPath(filePath)
返回一个可能为nil的Optional值。您应该在使用之前进行检查:
if let filePath = NSBundle.mainBundle().pathForResource("crankringtone", ofType: "mp3"){
if let filePathUrl = NSURL.fileURLWithPath(filePath) {
audioPlayer = AVAudioPlayer(contentsOfURL: filePathUrl, error: nil)
}
} else {
println("file path is empty")
}
答案 2 :(得分:0)
您应始终先获取网址,然后根据需要提取路径:
import UIKit
import AVFoundation
class ViewController: UIViewController {
@IBOutlet weak var playPause: UIButton! // create your button outlet
var audioPlayer:AVAudioPlayer? = nil // create an optional audio player
override func viewDidLoad() {
super.viewDidLoad()
// you can create your url as follow (no need for a path)
if let fileUrl = NSBundle.mainBundle().URLForResource("alarm", withExtension: "mp3") {
// if url is ok you can load your audio
audioPlayer = AVAudioPlayer(contentsOfURL: fileUrl, error: nil)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func playPauseAction(sender: AnyObject) {
// here you can check if the player was successfully created
if let audioPlayer = audioPlayer {
// here you can check if your player is playing
if audioPlayer.playing {
//if playing lets pause it
audioPlayer.pause()
// and change it's title to "Play"
playPause.setTitle("Play", forState: UIControlState.Normal)
} else {
//if plaused lets play it
audioPlayer.play()
// and change it's title to "Pause"
playPause.setTitle("Pause", forState: UIControlState.Normal)
}
}
}
}
答案 3 :(得分:0)
在你的代码中,你已经声明了变量audioPlayer var audioPlayer:AVAudioPlayer!
感叹号意味着它在打开时不能为零。
所以,在这段代码中:
if var filePath = NSBundle.mainBundle().pathForResource("crankringtone", ofType: "mp3"){
var filePathUrl = NSURL.fileURLWithPath(filePath)
audioPlayer = AVAudioPlayer(contentsOfURL: filePathUrl, error: nil)
} else {
println("file path is empty")
}
你有一个名为filePathUrl
的变量。该变量正在使用NSURL.fileURLWithPath(filePath)
。这可以返回nil
。如果是,那么您的变量filePathUrl
为零。然后当你在audioPlayer
中使用它时,它是零,所以audioPlayer
返回nil。
但请记住,audioPlayer
有一个!
。它不能是零。所以你能做的(最简单的选择)就是有一个额外的if语句:
if let filePath = NSBundle.mainBundle().pathForResource("crankringtone", ofType: "mp3"){
if let filePathUrl = NSURL.fileURLWithPath(filePath) {
audioPlayer = AVAudioPlayer(contentsOfURL: filePathUrl, error: nil)
}
} else {
println("file path is empty")
}
这个额外的if语句双重检查filePathUrl
不是nil。如果是,则将程序发送到else语句。如果它不是nil,那么它允许audioPlayer
做它的事情。并且,因为我们知道值不是nil,所以audioPlayer不会返回错误。
答案 4 :(得分:0)
当您点按一个按钮并调用playSlowAudio
函数时,很可能发生崩溃。
问题是您正在使用audioPlayer
隐式解包的可选项。如果播放器的初始化失败(例如,找不到文件),则audioPlayer
将为nil
。因此,当调用按钮操作时,audioPlayer.stop()
会在调用audioPlayer
之前尝试解包stop()
,这会导致崩溃。
要修复,请将audioPlayer
更改为常规可选:
var audioPlayer:AVAudioPlayer?
并使用更安全的可选链接:
audioPlayer?.stop()
所以完整的例子将如下所示:
import UIKit
import AVFoundation
class PlaySoundsViewController: UIViewController {
var audioPlayer:AVAudioPlayer?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if var filePath = NSBundle.mainBundle().pathForResource("crankringtone", ofType: "mp3"){
var filePathUrl = NSURL.fileURLWithPath(filePath)
audioPlayer = AVAudioPlayer(contentsOfURL: filePathUrl, error: nil)
} else {
println("file path is empty")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func playSlowAudio(sender: UIButton) {
audioPlayer?.stop()
}
}