質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
86.12%
Swift

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

クロージャ

クロージャは、プログラミング言語における関数オブジェクトの一種です。 引数以外の変数を実行時の環境ではなく、 自身が定義された環境において解決することを特徴とします。

解決済

クロージャを使ってReturnを使わないメリットとは?

Ren_Toyokawa
Ren_Toyokawa

総合スコア15

Swift

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

クロージャ

クロージャは、プログラミング言語における関数オブジェクトの一種です。 引数以外の変数を実行時の環境ではなく、 自身が定義された環境において解決することを特徴とします。

2回答

0グッド

4クリップ

4087閲覧

投稿2016/12/30 13:59

クロージャを使いReturnを使わないメリットとは
SwiftでTwitterクライアントを作ろうとしています。

Qiitaですでに作ってらっしゃる方がいらしたので、参考にしようと思ったのですが

Accountを取得する際や、TimeLineを取得する際、頑なにreturnは使わず、クロージャを使い、CallBackでAccountや、TimeLineを返しています。

実際のソースは下記のようなものです。

swift

1func getAccounts(callback: @escaping ([ACAccount]) -> Void) { 2 let accountType: ACAccountType = accountStore.accountType(withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter) 3 accountStore.requestAccessToAccounts(with: accountType, options: nil) { (granted: Bool, error: Error?) -> Void in 4 guard error == nil else { 5 print("error! \(error)") 6 return 7 } 8 guard granted else { 9 print("error! Twitterアカウントの利用が許可されていません") 10 return 11 } 12 13 let accounts = self.accountStore.accounts(with: accountType) as! [ACAccount] 14 guard accounts.count != 0 else { 15 print("error! 設定画面からアカウントを設定してください") 16 return 17 } 18 print("アカウント取得完了") 19 callback(accounts) 20 } 21}

このような場合ですと、処理が追いづらく、可読性が低いのではないか?と疑問に思ったのですが、クロージャを使う理由はどう言ったものがあるのでしょう。

Swiftのクロージャしかわからないのですが、一応、値のキャプチャなどは理解しているつもりです。

ちなみに、参考にさせていただいている記事はこちらです。
こちらの記事を貶めようと思っての投稿ではございませんので、何卒、ご了承ください
http://qiita.com/keisei_1092/items/32a96dbdb6bc394b0e8e#gettimeline

以上、ご回答のほど、よろしくおお願い致します。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答2

4

簡単に言うとメソッドの中に通信処理が入り非同期で実行される為、その値の取得後に処理を戻したいという事でクロージャーを使っているということですかね。

以下の処理は引数で受け取った値を足して戻すメソッドです、これは同期的に処理されるのでそのまま足した値が戻されます。

swift

1func add(value1: Int, value2: Int) -> Int { 2 return value1 + value2 3} 4 5// 呼び出し側 6let value = add(value1: 2, value2: 3) 7print(value) 8//=> 5

非同期処理がメソッドの中に入っている場合、普通にreturnで値を返すと通信処理を待っていないので結果が反映されない状態で返されます。

swift

1func getTweetCount() -> Int { 2 var tweetCount = 0 3 4 通信処理メソッド { count in 5 6 // 通信後に呼ばれるブロック 7 tweetCount = count 8 } 9 10 // 通信後の処理を待っていないので毎回 0 が返されます。 11 return tweetCount 12} 13 14 15// 呼び出し側 count は毎回0 16var count = getTweetCount() 17print(count) 18//=> 0

最後にクロージャーを使用した場合、非同期の通信処理が終わったところでクロージャーを実行して呼び出し元に処理を返しています。

swift

1func getTweetCount(callback: @escaping (Int) -> Void) { 2 var tweetCount = 0 3 4 通信処理メソッド { count in 5 6 // 通信後に呼ばれるブロック 7 callback(count) 8 } 9} 10 11 12// 呼び出し側 13getTweetCount { count in 14 15 // 非同期処理後に呼ばれる 16 print(count) 17} 18

投稿2016/12/30 14:30

編集2016/12/30 14:32
_Kentarou

総合スコア8488

ttah, Raleigh, Ren_Toyokawa👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Ren_Toyokawa

2017/01/18 23:31

より詳細なご回答、ありがとうございます。 クロージャの理解や、通信処理について知ることができました。

3

ベストアンサー

例として挙げられているコードの場合、requestAccessToAccounts()メソッドは非同期的に実行されるので、結果が返ってくる前にメソッドが終了してしまうため、returnで通常の戻り値を返しても意図した通りに動きません。

非同期メソッドから値を返す方法はいくつかありますが、例のコードで行われているようにクロージャを渡して、実行完了のタイミングで呼び出してもらう方法や、Promiseオブジェクトを返して完了した後で実際の値が取得できるようにする、などがあります。

いずれにせよ、単にreturnを使いたくないからそうしているわけではなく、非同期メソッドの結果を扱わなければならないため、クロージャを利用することを選択した、ということだと思います。

投稿2016/12/30 14:09

退会済みユーザー

退会済みユーザー

総合スコア0

fuzzball, _Kentarou, maisumakun👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Ren_Toyokawa

2017/01/18 23:29

そうそうにご回答いただき、ありがとうございます。 返答遅くなり申し訳在りません。 その後自分で、色々調べ、腑に落ちました。 クロージャの特性に関して、まだまだ勉強が足りなかったようです。 非同期処理に関しても、デザインパターンなどを学ぶ必要があると気づくこともできました。 回答していただき、まことにありがとうございます。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Swift

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

クロージャ

クロージャは、プログラミング言語における関数オブジェクトの一種です。 引数以外の変数を実行時の環境ではなく、 自身が定義された環境において解決することを特徴とします。