Ios 对新手的快速帮助
我收到以下错误消息,无法找出我做错了什么。这是我的第一个程序,不知道如何调试它 错误消息: 致命错误:在展开可选值时意外发现nil (lldb) 代码:Ios 对新手的快速帮助,ios,swift,Ios,Swift,我收到以下错误消息,无法找出我做错了什么。这是我的第一个程序,不知道如何调试它 错误消息: 致命错误:在展开可选值时意外发现nil (lldb) 代码: 在使用前,需要检查filePathUrl的值是否为非零 NSURL.fileURLWithPath(filePath)返回一个可选值,该值可能为零。使用前应检查: if let filePath = NSBundle.mainBundle().pathForResource("crankringtone", ofType: "mp3"){
在使用前,需要检查
filePathUrl
的值是否为非零 NSURL.fileURLWithPath(filePath)
返回一个可选值,该值可能为零。使用前应检查:
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")
}
在代码中,您已经声明了变量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
中使用它时,它是nil,因此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
是否为空。如果是,则将程序发送到else语句。如果它不是nil,那么它允许audioPlayer
执行它的操作。而且,因为我们知道该值不是零,audioPlayer不会返回错误。当您点击按钮并调用playSlowAudio
函数时,很可能会发生崩溃
问题是您正在为audioPlayer
使用隐式展开的可选选项。如果播放机初始化失败(例如,找不到文件),则audioPlayer
将为nil
。因此,当调用按钮操作时,audioPlayer.stop()
在调用stop()
之前尝试打开audioPlayer
,这会导致崩溃
要修复此问题,请将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()
}
}
如果var…
是合法的,但是在大多数情况下,如果let…
是更好的选择cases@bolot我从未在官方文件中看到过如果变量…
。我不知道这是合法的。无论如何,这绝对不是最佳实践。从苹果在Swift上的文档:“您可以将常量和变量与可选绑定一起使用。如果您想在If语句的第一个分支中操作actualNumber的值,可以改为写入If var actualNumber,并且optional中包含的值将作为变量而不是常量提供。“@vacawama谢谢你的推荐。我猜我只是犯了一个粗心的错误。@Sw在哪一行出现了致命错误:在解包可选值(lldb)时意外地发现了nil
发生了?我之前在那里有一个错误的mp3文件名-这就是问题所在吗?您仍然遇到崩溃吗?或者它只是不起作用?没有崩溃。它只是不起作用。我把println的一切都搞定了,并确认音频播放器没有被创建。
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()
}
}