🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

599閲覧

guard文が必要な理由

ruuuu

総合スコア176

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/12/19 03:36

Notificationについて、学習していたのですが、疑問点があり、質問させて貰いました。

// MARK: - ライフサイクル override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) configureObserver() //Notification発行 } // MARK: - Notification /// Notification発行 func configureObserver() { let notification = NotificationCenter.default notification.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) notification.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) print("Notificationを発行") } /// キーボードが表示時に画面をずらす。 @objc func keyboardWillShow(_ notification: Notification?) { guard let rect = (notification?.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue, let duration = notification?.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else { return } UIView.animate(withDuration: duration) { let transform = CGAffineTransform(translationX: 0, y: -(rect.size.height)) self.view.transform = transform } print("keyboardWillShowを実行") } /// キーボードが降りたら画面を戻す @objc func keyboardWillHide(_ notification: Notification?) { guard let duration = notification?.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? TimeInterval else { return } UIView.animate(withDuration: duration) { self.view.transform = CGAffineTransform.identity } print("keyboardWillHideを実行") }

こちらは、リンク先に提示されていたコードなのですが、以下の部分でguard文が使用されています。何故guard文が必要なのかが分かりません...
guard文を使わない場合デメリットがあるのでしょうか?

guard let rect = (notification?.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue, let duration = notification?.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else { return }

どなたか、ご教授頂けましたら幸いです

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thyda.eiqau

2019/12/19 03:41

guard文が何か分からないということですか?
ruuuu

2019/12/19 03:52

説明不足ですみません。 いえ、guard文が何かは理解できるのですが、質問に掲示させて頂いたコード内で、guard文が何故必要なのかなと思った次第です。例えば、単純に、guard文を使わずに、「let rect = (notification?.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue」こちらのような形ではダメなのかなと思ったんですよね...
guest

回答1

0

ベストアンサー

そのあとの処理で rectduration が必須だからです。
guard を使わずに、その後の処理を安全に (Crashしないように) 進めようとすると、

  • try で囲む
  • 初期化のあとで if(rect == nil || duration == nil) { return }

などの処理が必要です。guard let しなくても上記の書き方をすれば問題はないですが、冗長です。

わかりやすいQiitaがありましたので貼っておきます。 Swift の guard は正しく使いましょう - Qiita

投稿2019/12/19 04:40

thyda.eiqau

総合スコア2982

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ruuuu

2019/12/19 05:17

ご回答ありがとうございます。 > その後の処理を安全に (Crashしないように) 進めようとすると、 ご回答頂きましたこちらの部分なのですが、「rect」が「nil」になる可能性がどうしても分らない部分でして... configureObserver関数内では確実に値が入ってくる可能性があるのではないでしょうか...?
eytyet

2019/12/19 06:27

「確実に値が入ってくる」と思う根拠は何ですか?私は逆に何が来るかわからないと思います。keyboardWillShow(_ notification: Notification?) はiOSから呼び出されますが、そのとき必ずnotification?.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey]に値が入っている事を前提にはできないと理解しています。 たとえAppleのドキュメントに保証すると書いてあったとしても、次のiOSでは変わるかもしれません。誰かが勝手にnotificationを発行しているかもしれません。必ず値が来ると信じるに足る根拠は存在しないのではないでしょうか。 そもそも論として、プログラマとしては、絶対クラッシュさせないようにコードを構築する事を考える方が健全であると思います。そのため、たとえ仕様で保証してくれていても、?をみたら安全のためガードしておくくらいの姿勢が好ましいんじゃないかと思っています。
ruuuu

2019/12/19 06:37

アドバイス頂き、ありがとうございます。 自分自身、何をnilチェックするべきか、分かっていない部分があり、まだまだ勉強不足だと痛感いたしました。 できるだけ、nilの可能性があるものは、オプショナルチェーニングをするなり、guard文を使うなどしていきたいと思います。
eytyet

2019/12/19 07:02

オプショナル型は全部nilチェックする、という前提でよいと思います。それが必要なのでオプショナル型にしているわけで、そうでないならオプショナルのない型を使っています。つまり、オプショナルであるということは、nilである場合が必ずあるという事です。私はas!を使う時を、nilではない事が自分で保証できるときだけ(直前に自分で代入済みなど)に限定しています。 そうしていない(as!を多用する)チュートリアルや記事もみかけますが、本来は全部対応するべきです。?に対処するコードで長くなったり複雑になったりするので、意図的にやめているという事なのでしょうけど、そういうコードをコピペして使ってはいけません。簡単にクラッシュします。 見分け方は簡単で、as!を使うコードは要注意です。as?は安全です。
thyda.eiqau

2019/12/19 11:55

eytyetさん、補足ありがとうございます。おっしゃるとおりで、「オプショナル」は「nilかもしれない」と同義ですので、ほとんど全てのシチュエーションにおいて、nilだった場合の処置をする(ハンドルする)ことが必要ですね。
ruuuu

2019/12/20 02:44

ご助言ありがとうございます。 nilの値の取り扱いには、気をつけ、コーディングしていきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問