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

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

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

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

Swift

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

Q&A

解決済

2回答

3299閲覧

なぜクロージャではselfを使うのか【Swift】

kazuki_user

総合スコア147

iOS

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

Swift

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

0グッド

1クリップ

投稿2020/09/17 09:03

編集2020/09/17 14:37

## なぜクロージャではselfを使うのか【Swift】

**selfをキャプチャすることを明示するため。**と書かれていたのですが、
参考サイト

以下コードの場合、下記の記述は正しいでしょうか?

関数scope_3へのキャプチャを明示する為、self.scope_3と記述する。

因みにselfは、Fooクラスを指しています。

#### 質問

  • Fooクラスを キャプチャしているのでしょうか?
  • self.scope_3(= 関数scope_3) をキャプチャしているのでしょうか?

関数scope_3の変数teteへの参照を保持しているので、後者の説明がしっくり来るのですが...????
参考サイトの考えによると、前者が正しいっぽいですが..

swift

1// scope_4関数は、scope_3関数から返されたクロージャを2回実行しています。 2class Foo { 3 func scope_3() -> () -> Void { 4 var tete = 10 5 let closure = { tete += 1 6 print(tete) 7 } 8 return closure 9 } 10 11 func scope_4() { 12 let tutu = self.scope_3() 13 tutu() 14 tutu() 15 } 16}

質問は以上です。
お時間あるときに、ご返信頂けましたら幸いです????

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

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

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

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

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

guest

回答2

0

質問のコードは、

  • 引数でクロージャを受け取っているところがない
  • クロージャFooの変数やメソッドを一切使っていない
  • scope_4で受け取ったクロージャはscope_4の終了で存在しなくなる

ので、質問に貼ってあるqiitaの記事に書いてあることとまったく関係がないコードになっています。

じっさい、

swift

1class Foo { 2 func scope_3() -> () -> Void { 3 var tete = 10 4 let closure = { tete += 1 5 print(tete) 6 } 7 return closure 8 } 9 10 func scope_4() { 11 let tutu = scope_3() 12 tutu() 13 tutu() 14 } 15}

としても動きますね。

投稿2020/09/18 01:21

quickquip

総合スコア11038

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

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

kazuki_user

2020/09/18 02:27

ご返信ありがとうございます。 https://qiita.com/st43/items/20d8b643c1f2431b4609 このQiitaにて、 > 循環参照を起こす危険性があるので、クロージャーの中で親スコープを参照するときはselfをつけることになります。 とあるのですが、 「なぜクロージャではselfを使うのか」の答えとしては、 循環参照を防ぐ為。で良いのでしょうか?
quickquip

2020/09/18 03:54 編集

循環参照を起こす危険性があるから防ぐためにクロージャーの中で親スコープを参照するときはselfをつける が真であっても クロージャではselfを使うは循環参照を防ぐ為 が真であるとは限らないのでは? というのが素直な感想です。 あと > 循環参照を起こす危険性があるので、クロージャーの中で親スコープを参照するときはselfをつけることになります にはギャップがあるように思います。(納得感がありません)
kazuki_user

2020/09/18 04:06 編集

了解です。 ご返信ありがとうございました。????‍♀️
quickquip

2020/09/18 04:20 編集

https://docs.swift.org/swift-book/LanguageGuide/Closures.html#ID546 > Writing self explicitly lets you express your intent, and reminds you to confirm that there isn’t a reference cycle. [雑訳]selfを明に書くことで、自分の意図を明記することになり、循環参照が存在しないよう確認することに注意するようになります。 (Escaping Closuresは)循環参照を起こす危険性があるので、(プログラマにそれを意識させるために)クロージャーの中で親スコープを参照するときはselfをつけることになります だったなら納得感でます。 selfを付けることが循環参照を防ぐことに直結しているわけではなくて、コードの意図が明確になり、プログラマが循環参照しないかに意識を向けて書くようになる、という感じではないでしょうか。
quickquip

2020/09/18 04:27

実際selfは強参照だから循環参照を防ぐ役には立たないですよね。 (selfを書くことで)ここに強参照があるぞ、とプログラマが気づくことが役に立つのでは。
kazuki_user

2020/09/18 04:31 編集

> selfを明示的に書くことで、自分の意図を明記する > 循環参照を起こす危険性があるので、プログラマにそれを意識させるために、クロージャーの中で親スコープを参照するときはselfをつけることになります > selfは強参照 大変勉強になりました。????‍♂️ 次は、強・弱参照や、循環参照についてしっかりと学ぼうと思います。ありがとうございました。
guest

0

自己解決

Escaping Closuresは)循環参照を起こす危険性があるので、

(プログラマにそれを意識させるために)クロージャーの中で親スコープを強参照するときはselfをつける。

selfを付けることが循環参照を防ぐことに直結しているわけではなくて

コードの意図が明確になり、循環参照しないかにプログラマが意識を向けて書くようになる、

つまり、明示的なselfには、循環参照が存在しないよう確認を促す役割がある。

投稿2020/09/17 14:30

編集2020/09/18 04:47
kazuki_user

総合スコア147

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問