1. ホーム
  2. xcode

クロージャをSwift 3に更新する - @escaping

2023-09-12 08:35:50

質問

私は自分のコードをXcode 8.0 beta 6にアップデートしましたが、新しいノンエスケープクロージャーのデフォルトについてと思われるものに行き詰まりました。以下のコードで、Xcode は、以下のものを追加するよう提案します。 @escaping の前に completion: を追加しましたが、それでもコンパイルされず、堂々巡りになってしまいます。*

( EDIT : 実は、@escapingは、以下のように追加する必要があります。 の後に completion: の後に、Xcodeが提案するように。アラートはまだ表示されるかもしれませんが、クリーニングとコンパイルで削除されます)* このコードは、アップデートされたSwift 3で動作するようにどのように書き直し/修正する必要がありますか? 私は新しいマニュアルを見ましたが、適切なコードサンプルを見つけることができませんでした。

func doSomething(withParameter parameter: Int, completion: () -> ()) {
    // Does something

    callSomeOtherFunc(withCompletion: completion)
  }

// Calling the method and execute closure 
doSomething(withParameter: 2) {
  // do things in closure
}

どんな助けでも大いに感謝します

どのように解決するのですか?

Swift 3: クロージャパラメータの属性が、パラメータ タイプ に適用され、パラメータ自体には適用されません。

Swift 3 より前のバージョンでは、クロージャの属性 @autoclosure@noescape は、クロージャの属性であった パラメータ の属性でしたが、現在はパラメータ タイプ に変更されました。以下の受理されたSwiftの進化提案を参照してください。

パラメータ型属性に関連する具体的な質問 @escaping (同じ新しいルールが適用されます)、クロージャパラメータをデフォルトで非エスケープにするために受け入れられた Swift の進化の提案で説明されたように。

これらの提案は現在、両方とも Xcode 8 のベータ版で実装されています ( Xcode 8 beta 6 のリリースノート アクセスには開発者アカウントのログインが必要です)

<ブロッククオート

Xcode 8 beta 6 の新機能 - Swift コンパイラ。Swift 言語

クロージャパラメータはデフォルトでノンエスケープであり、明示的に でアノテーションされるのではなく @noescape . 使用方法 @escaping を使ってください。 を使います。 @autoclosure(escaping) は次のように書かれます。 @autoclosure @escaping . アノテーションは @noescape@autoclosure(escaping) は非推奨です。(SE-0103)

...

Xcode 8 betaの新機能 - SwiftとApple LLVMコンパイラ。Swift 言語

この @noescape@autoclosure 属性は、パラメータ名の前ではなく は、パラメータ名の前ではなく、パラメータタイプの前に書かなければなりません。[SE-0049]

したがって、デフォルトでない @escaping 属性は次のように使用します。 タイプ に適用され、パラメータそのものではなく、クロージャパラメータの

func doSomething(withParameter parameter: Int, completion: @escaping () -> ()) {
    // ...
}


(コメントはSOでは永続的なデータではないので、下のupvotedコメントで質問に対する私の答えを含む)

@Cristi Băluță: "エスケープって何するんですか?このキーワードは見たことがない swift3自動変換の前に... "。

参照:リンク先の 上記のSE-0103進化提案 (およびベータ 6 リリース ノートからの引用文): 以前は、クロージャ パラメータはデフォルトでエスケープされていましたが (したがって、エスケープのための明示的な注釈の存在は必要ありません)、現在は代わりに、デフォルトで非エスケープになっています。そのため @escaping を追加し、クロージャパラメータが(デフォルトの挙動とは逆に)エスケープする可能性があることを明示的にアノテーションしています。これはまた、なぜ @noescape が非推奨になった理由もここにあります(デフォルトの挙動をアノテートする必要がない)。

クロージャパラメータがエスケープされることの意味を説明するために、私は 言語リファレンス - 属性 :

メソッドまたは関数宣言のパラメータの型にこの属性を適用すると、パラメータの値を後で実行するために保存できることを示すことができます。 この属性は、パラメータの値が後の実行のために保存されることを示します。これは、値が呼び出しの寿命よりも長くなることを許可していることを意味します。 これは、値が呼び出しの寿命よりも長くなることを意味します。