快速帮助新手

时间:2015-01-27 01:45:19

标签: ios swift

我收到以下错误消息,无法弄清楚我做错了什么。这是我的第一个程序,对如何调试它并不太了解。

错误讯息:

  

致命错误:在展开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()
    }
}

5 个答案:

答案 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()
    }
}