26570


野球のデータベースにRealmSwiftを使っています。

打者→試合→打席→打席の内容と、４階層のリレーションを組んであります。  
その中で、既に登録済みの試合の打席の次の打席ならばRealmに追加登録。  
まだ入力していなければ新規登録。  
という条件分岐のコードで、シミュレーターで新たに走らせるとタイトルの通り、  
「fatal error: unexpectedly found nil while unwrapping an Optional value」  
が発生します。

Realmに一件でもデータが入っていればクラッシュはしません。  
nilになっているから。ということだとは思いますが、どうやって調べたら良いでしょうか？  
念のため、クラッシュ時のスクショも貼ります。  
お解りになる方がいらっしゃればご教授下さい。  
お願いします。

[code]

    let games = realm.objects(Game).filter("batDate == %@ && gamesCount == %@", textField7.text!, textField8.text!)
            print(games)
            for game in games {
                //参照して同じ月日の同じ試合があれば打席を後ろに追加する
                if (game.batDate == textField7.text!) && (game.gamesCount == textField8.text!) {
                    let realm = try! Realm()
                    try! realm.write {
                        //試合
                        let game = Game()
                        game.batDate = textField7.text!
                        game.gamesCount = textField8.text!
                         //打者→試合への関連付け
                        let batter = realm.objects(Batter).last!
                        batter.games.append(game)
                    }
                //同じ月日同じ試合がなければ新規の試合を登録
                } else {
                    let realm = try! Realm()
                    try! realm.write {
                        //試合
                        let game = Game()
                        game.batDate = self.textField7.text!
                        game.gamesCount = self.textField8.text!
                        //打者→試合への関連付け
                        let batter = realm.objects(Batter).last!
                        batter.games.append(game)
    
                        //Realmに書き込み
                        realm.add(game)
                    }
                }
            }
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/58oNv.png)](https://i.stack.imgur.com/58oNv.png)


CC BY-SA 3.0
2016-06-08T12:30:09.613
26565
2016-06-08T19:00:13.140
2016-06-08T13:32:53.633
5519
13156
question
swift
fatal error: unexpectedly found nil while unwrapping an Optional valueを解決したい！


[swiftでfatal error: unexpectedly found nil while unwrapping an Optional
valueが出た時のデバッグ方法](https://ja.stackoverflow.com/questions/7231/swift%E3%81%A7fatal-
error-unexpectedly-found-nil-while-unwrapping-an-optional-
value%E3%81%8C%E5%87%BA%E3%81%9F%E6%99%82)は読まれましたか?(PC版で)あなたの質問を開くと「関連する質問」のトップに表示されますし、"fatal
error: unexpectedly found nil while unwrapping an Optional
value"で検索してもすぐに見つかります。(エラーが出た時に対処方法がわからなければ、エラーメッセージ丸ごとで検索してみる、と言うのは基本的な情報収集のテクニックだと思うのですが…。)エラーについてご質問を書かれる場合、リンク先に記載されたような方法で、出来るだけ原因となる行を絞り込むといったことはしてみてください。

ただ、あなたのコードを見るといくつかお薦めできない書き方があるので、その部分も含めて回答として書かせていただきます。

* * *

あなたのわずか20行ちょっとのコードの中に、forced
unwrappingを表す`!`が10回も登場しています。この`!`は「もし値が`nil`だったら、アプリをクラッシュさせてしらせろ」という意味ですから、実際にアプリを動かした時に絶対に`nil`にはならないことが確実な場合以外には使うべきではありません。

XcodeではOptional型ではいけない場所にOptional型の式を書いた場合、コードサジェスチョンとして`!`の追加だけを勧めてくるのですが、安易にその修正を受け入れてはいけません。

このような場合、`!`を付ける以外に

  * `??`演算子を使ってデフォルト値を指定する
  * Optional bindingを使って`nil`でないことを確認する

といったのが代表的な方法です。

* * *

1つめの「`??`演算子を使ってデフォルト値を指定する」は、こんな形で使います。

[code]

            let text7 = textField7.text ?? "" //`textField7.text`がnilならば、`text7`には""(空文字列)が入る
            let text8 = textField8.text ?? "" //`textField8.text`がnilならば、`text8`には""(空文字列)が入る
    
[/code]

あなたが提示されたコードの前に上の2行を付け加えて、`textField7.text!`と`textField8.text!`は全て`text7`と`text8`に置き換えてみてください。

* * *

2つ目のOptional bindingは次のようになります。

[code]

            if let batter = realm.objects(Batter).last {
                //`realm.objects(Batter).last`がnilでないときだけ、このブロック内のコードが実行される
                batter.games.append(game)
            }
    
[/code]

あなたのコードの

[code]

            let batter = realm.objects(Batter).last!
            batter.games.append(game)
    
[/code]

を上のように書き換えてみてください。

* * *

どちらの書き方も、どこかで見たことがある、もしくは、すでにあなたのコードの他の部分に使われているのではないでしょうか。 **forced
unwrappingを表す`!`は確実にnilでないことがわかっている時以外には使わない**
ように心がけて、`!`が現れているところを自分で書き換えられるようにしてください。

`try!`も「実行時エラーが出たらアプリをクラッシュさせてしらせろ」の意味ですからあまりお薦めできず、ちゃんと`do {}
catch`で囲んだほうがいいのですが、質問タイトルからずれてしまいますので、コードは省略します。 **そもそもnil落ちしにくいコードの書き方**
として、上記の2種類の修正をしてアプリの動作がどうなるか、ぜひお試しください。


CC BY-SA 3.0
2016-06-08T19:00:13.140
26570
2016-06-08T19:00:13.140
2017-04-13T12:52:39.113
-1
13972
26565
answer