1. ホーム
  2. swift

[解決済み] Swift のオプションのエスケープクロージャーパラメータ

2022-04-22 03:42:10

質問

与えられた。

typealias Action = () -> ()

var action: Action = { }

func doStuff(stuff: String, completion: @escaping Action) {
    print(stuff)
    action = completion
    completion()
}

func doStuffAgain() {
    print("again")
    action()
}

doStuff(stuff: "do stuff") { 
    print("swift 3!")
}

doStuffAgain()

を作る方法はないのでしょうか? completion パラメータ(および action という型の Action? を保持し、さらに @escaping ?

型を変更すると、次のようなエラーが発生します。

エスケープ属性は、関数型にのみ適用されます。

を削除する @escaping 属性があるため、コードはコンパイルされて実行されますが、正しいとは言えないようです。 completion クロージャは関数のスコープをエスケープしています。

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

があります。 SR-2552 という報告 @escaping が関数型のエイリアスを認識しないため、エラーになります。 @escaping attribute only applies to function types 関数シグネチャで関数型を拡張することで回避することができます。

typealias Action = () -> ()

var action: Action? = { }

func doStuff(stuff: String, completion: (@escaping ()->())?) {
    print(stuff)
    action = completion
    completion?()
}

func doStuffAgain() {
    print("again")
    action?()
}

doStuff(stuff: "do stuff") {
    print("swift 3!")
}

doStuffAgain()

EDIT 1: :

実はxcode 8のベータ版で、このバグは SR-2552 そのバグを修正すると、新しいバグ(あなたが直面しているもの)が発生し、まだ未解決です。 SR-2444 .

回避策 マイケル・イルゼマン は、一時的な解決策として @escaping 属性は、オプションの関数型から削除されます。 をエスケープすることで、この関数を維持することができます。 .

func doStuff(stuff: String, completion: Action?) {...}

EDIT 2: :

その SR-2444 パラメータ位置のクロージャを明示的にクローズしました。 はありません。 でマークする必要があります。 @escaping はエスケープされますが、オプションのパラメータである は暗黙のうちにエスケープされています。 ((Int)->())? の同義語です。 Optional<(Int)->()> オプションのクロージャはエスケープされます。