サーチ…


前書き

スウィフトドキュメンタリーから

クロージャは、クロージャが関数の引数として渡されるときに関数をエスケープすると言われますが、関数が返った後に呼び出されます。クロージャーをパラメーターの1つとして使用する関数を宣言すると、そのパラメーターの型の前に@エスケープを書いて、クロージャーがエスケープできることを示すことができます。

非エスケープクロージャ

スイフト1と2では、デフォルトでクロージャパラメータがエスケープしていました。クロージャーが関数本体をエスケープしないことが分かっていたら、@ noescape属性でパラメーターをマークできます。

Swift 3では、これと逆の方法があります。クロージャのパラメータはデフォルトではエスケープされません。関数をエスケープする場合は、@escaping属性でマークする必要があります。

class ClassOne {
  // @noescape is applied here as default
  func methodOne(completion: () -> Void) {
    // 
  }
}

class ClassTwo {
  let obj = ClassOne()
  var greeting = "Hello, World!"

  func methodTwo() {
    obj.methodOne() {
      // self.greeting is required
      print(greeting)
    }
  }
}

クロージャをエスケープする

スウィフトドキュメンタリーから

@エスケープ

この属性をメソッドまたは関数宣言のパラメーターの型に適用し、後で実行するためにパラメーターの値を格納できることを示します。これは、その値がコールの存続期間を超えていることを許可されていることを意味します。エスケープ型の属性を持つ関数型パラメータでは、selfを明示的に使用する必要があります。プロパティまたはメソッドの場合

class ClassThree {

    var closure: (() -> ())?

    func doSomething(completion: @escaping () -> ()) {
        closure = finishBlock
    }
}

上記の例では、完了ブロックはクロージャーに保存され、文字通り関数呼び出しを超えて存続します。したがって、コンパイラは補完ブロックを@エスケープとしてマークする必要があります。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow