[解決済み] Swift の @escaping と Completion ハンドラ
質問
Swiftの'Closure'をより正確に理解しようとしています。
しかし
@escaping
と
Completion Handler
は難解すぎる
Swiftの投稿や公文書をたくさん探しましたが、まだ足りないと感じました。
公式ドキュメントのコード例です。
var completionHandlers: [()->Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping ()->Void){
completionHandlers.append(completionHandler)
}
func someFunctionWithNoneescapingClosure(closure: ()->Void){
closure()
}
class SomeClass{
var x:Int = 10
func doSomething(){
someFunctionWithEscapingClosure {
self.x = 100
//not excute yet
}
someFunctionWithNoneescapingClosure {
x = 200
}
}
}
let instance = SomeClass()
instance.doSomething()
print(instance.x)
completionHandlers.first?()
print(instance.x)
を使用する方法と理由は2つあると聞きました。
@escaping
1つはクロージャを格納するため、もう1つは非同期操作のためです。
以下は私の質問です。 :
まず、もし
doSomething
が実行されたら
someFunctionWithEscapingClosure
が実行され、そのクロージャはグローバル変数の配列に保存されます。
クロージャは{self.x = 100}だと思います。
どのように
self
で、グローバル変数に保存された{self.x = 100}で
completionHandlers
に接続することができます。
instance
のオブジェクトは
SomeClass
?
第二に、私は
someFunctionWithEscapingClosure
をこのように理解します。
ローカル変数のクロージャを格納するために
completionHandler
をグローバル変数completionHandlersに格納する。
we using
キーワードをエスケープしてください。
を使わずに
@escaping
キーワード
someFunctionWithEscapingClosure
が返す、ローカル変数
completionHandler
はメモリから削除されます。
@escaping
はそのクロージャをメモリに保持します。
これで良いのでしょうか?
最後に、この文法が存在すること自体が不思議なんです。
これは非常に初歩的な質問かもしれませんが。
ある関数を特定の関数の後に実行させたい場合。特定の関数呼び出しの後に、ある関数を呼び出せばいいのでは?
上記のパターンを使用することと、エスケープコールバック関数を使用することの違いは何ですか?
どのように解決するのですか?
Swiftの完了ハンドラのエスケープと非エスケープ。
Bob Leeがブログの記事で説明しているように Bobと一緒にSwiftで完了ハンドラ :
ユーザーがアプリを使用中に更新していると仮定します。その際 更新が完了したら、ユーザーに通知したいですよね。おそらく、「おめでとうございます。 おめでとうございます。
では、ダウンロードが完了した後にのみ、コードのブロックを実行するにはどうしたらよいでしょうか。 では、ダウンロードが完了した後にのみ、コードのブロックを実行するにはどうすればよいのでしょうか。さらに、あるオブジェクトをアニメーションさせるのに、ビュー コントローラーが次に移動した後、どのようにすればよいのでしょうか。 ビューコントローラを次のビューに移動した後に、特定のオブジェクトをアニメーション化するにはどうしたらよいでしょうか?さて、私たちは を設計する方法について説明します。
私の豊富な語彙リストによれば、完了ハンドラは以下のものを表します。
物事が完了したときに何かをする
Bobの投稿は、完了ハンドラについて明確にしてくれます(開発者の観点からすると、我々が理解する必要があることを正確に定義してくれています)。
クロージャをエスケープする。
関数の引数でクロージャを渡すと、関数本体が実行された後にそれを使ってコンパイラに返します。関数が終了したとき、渡されたクロージャのスコープは、クロージャが実行されるまで、メモリ上に存在し、存在します。
関数を含むクロージャをエスケープするにはいくつかの方法があります。
-
ストレージ。グローバル変数、プロパティ、または呼び出し関数の過去のメモリに存在する他のストレージにクロージャを格納する必要がある場合、実行され、コンパイラを返します。
-
非同期実行。デスパッチキューで非同期にクロージャを実行する場合、キューはメモリ内にクロージャを保持し、将来的に利用することができます。この場合、クロージャがいつ実行されるかはわかりません。
これらのシナリオでクロージャを使おうとすると、Swiftコンパイラはエラーを表示します。
このトピックについてより明確にするために、以下のサイトを参照してください。 この投稿はMediumにあります。 .
もう一つ、すべてのios開発者が理解する必要がある点を追加します。
- クロージャのエスケープ : エスケープクロージャとは、渡された関数が戻った後に呼び出されるクロージャのことです。言い換えれば は渡された関数より長生きする。
- エスケープしないクロージャ : 渡された関数内で呼び出されるクロージャ、つまり、関数が戻る前に呼び出されるクロージャです。
関連
-
Swift の Optional 値 && Optional のアンラップ時に予期せず nil が検出された場合の説明
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] クロージャ」と「ラムダ」の違いは何ですか?
-
[解決済み] Swiftでindexとelementでループを反復させる方法
-
[解決済み] Swiftの@selector()?
-
[解決済み] jQueryでHTML文字列をエスケープする
-
[解決済み] Swiftで警告を消すには?
-
[解決済み] Swiftのリバースレンジ
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
swift 4.0でのdispatch_async,dispatch_afterの使用について
-
[解決済み] Swiftで1つのビューコントローラの向きを縦向きのみに固定する方法
-
[解決済み] Protocol ... can only be used as generic constraint because it has Self or associated type requirements "とは、どういう意味ですか?
-
[解決済み] Swift 3でカスタム通知を作成するには?
-
[解決済み] Swift 1.2では、宣言は「final」と「dynamic」の両方にはなり得ないというエラーがある
-
[解決済み] Swiftでbutton.addTargetアクションにパラメータを付ける
-
[解決済み] ""内の二重引用符を印刷するには?
-
[解決済み] Swift: PREPROCESSORフラグ(`#if DEBUG`など)を使ってAPIキーを実装する方法とは?
-
[解決済み] SwiftUIで条件付きでビューを使用する
-
[解決済み] Swiftでenumの関連値を無視して比較する方法は?