質問: -1 //BGMを無限にループさせる **player.prepareToPlay() //音声を即時再生させる** player?.play() //音を再生させる } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. //playファイルの呼び出し、引数はファイル名 play("BMG.mp3") } @IBAction func wineTapped(sender:UIButton){ } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } ``` ちなみに、これはコードの問題じゃないのかもしれませんが、上記コードの**で囲まれた部分を修正してエラーがない状態にしても、シミュレーターを立ち上げた際にうまく立ち上がってくれません。 なお、Xcodeのバージョンは6.3.1(6D1002)です。 何か解決策があれば教えて下さい。 宜しくお願い致します。
回答: エラーを出さないようにする訂正のしかたは、 ``` player?.prepareToPlay() ``` が正解です。 Swiftにおけるオプショナル(Optional)型について、きっちり勉強なさって、理解するようにしてください。Appleが開発言語をObjective-CからSwiftに変更した理由の、半分以上がこのOptional型にあるといっても、過言ではないので。 Optional型は、nilが代入されることを許容する変数の型をいいます。裏返しに表現すると、一般の変数(非Optional型)は、nilを許容しません。代入しようとした値がnilだったら、プログラムエラーになり、アプリ全体が落ちます。 変数がnilを許容しないとはどういうことかというと、プログラム内のバグが潜む場所を、減らしていこうという意図です。iOSのフレームワークを、今後使っていくとわかってきますが、処理に失敗すると、返り値をnilとするメソッドが多数あります。そういうメソッドの後、返り値がnilかそうでないかで、条件分岐したプログラムを書いていれば、堅牢なプログラムに近づくんでしょうが、現実には、「ここでnilなんて、返ってこないでしょ?」ですましているプログラムが多数あります。そういう局面で、ちゃんと条件分岐するよう、プログラマに促す意味が、Optional型にあります。 なので、Optional型を生かすようなプログラムにするなら、こういうコードになるでしょう。 ``` func play(soundName:String){ let soundPath = NSBundle.mainBundle().bundlePath.stringByAppendingPathComponent(soundName) let url:NSURL? = NSURL.fileURLWithPath(soundPath) player = AVAudioPlayer(contentsOfURL: url, error: nil) // Optional Chainingを使う。 if let thePlayer = player { thePlayer.numberOfLoops = -1 thePlayer.prepareToPlay() thePlayer.play() } } ``` `if let thePlayer = player {}`は、ただの条件文ではなく、**Optional Binding**という特殊な構文です。Optional型の変数`player`の値が、nilでなければ、Unwrapした値を、非Optional型の変数`thePlayer`に代入します。(`else {}`を追加すると、`player`がnilだったときの処理を行えます。)