Swift 为什么AVAudioPlayer var等于零敏捷的

Swift 为什么AVAudioPlayer var等于零敏捷的,swift,null,avaudioplayer,nsbundle,Swift,Null,Avaudioplayer,Nsbundle,这是我的职责: func playMusic(filename :String!) { var playIt : AVAudioPlayer! let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil) if url == nil { println("could not find \(filename)") return } va

这是我的职责:

func playMusic(filename :String!) {
    var playIt : AVAudioPlayer!
    let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
    if url == nil {
        println("could not find \(filename)")
        return
    }
    var error : NSError?
    playIt = AVAudioPlayer(contentsOfURL: url, error: &error)
    if playIt==nil {
        println("could not create audio player")
        return
    }
    playIt.numberOfLoops = -1
    playIt.prepareToPlay()
    playIt.play()
}
我调试了我的应用程序,看到控制台告诉我:无法创建音频播放器

看起来我的
playIt
var为零


如何修复它?

您的代码还有另一个问题:一旦您找到
playIt
为什么是
nil
并修复它,您将发现
playMusic
运行时没有错误,但没有声音播放。
这是因为您在
playMusic
中声明了
playIt
作为局部变量。就在它开始播放时,您到达了
playMusic
的末尾,此时它的所有局部变量都超出范围,不再存在。在
playIt
开始播放后的几微秒,它就消失了

若要解决此问题,请将
playIt
声明为实例变量。以下是视图控制器的代码,该视图控制器使用您的
playMusic
方法和我建议的一项更改:

import UIKit
import AVFoundation


class ViewController: UIViewController {

  // Declare playIt here instead
  var playIt : AVAudioPlayer!

  override func viewDidLoad() {
    super.viewDidLoad()

    playMusic("sad trombone.mp3")
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }

  @IBAction func buttonPressed(sender: AnyObject) {

  }

  func playMusic(filename :String!) {
    // var playIt : AVAudioPlayer! *** this is where you originally declared playIt
    let url = NSBundle.mainBundle().URLForResource(filename, withExtension: nil)
    if url == nil {
      println("could not find \(filename)")
      return
    }
    var error : NSError?
    playIt = AVAudioPlayer(contentsOfURL: url, error: &error)
    if playIt==nil {
      println("could not create audio player")
      return
    }
    playIt.numberOfLoops = -1
    playIt.prepareToPlay()
    playIt.play()
  }

}
两种方法都可以尝试——将
playIt
声明为实例变量,并将
playIt
声明为
playMusic
中的局部变量。你会喜欢前者的


我也赞同nhgrif的建议:playMusic应该采用
字符串
字符串?
参数;不是
字符串

您是否检查了
error
变量的值?
error
保留问题的答案。可能还值得检查
url
的值,以确保它是您所认为的。。。另外,您不应该接受
字符串参数。。。要么使用
String
或者
String?
…大多数人倾向于避免强制展开(!),总是选择使用条件(?)。正如乔伊·德维拉所说。这是为了防止应用程序在返回nil时崩溃。