2016-03-27 10 views
6

私はSwiftプログラミング言語のマニュアルを読んでおり、エスケープクロージャーについて言及しています。クロージャをエスケープすることについては、「クロージャは関数の引数として渡されますが、関数が返された後に呼び出されます」という意味がわかりません。閉鎖をエスケープする例を教えてもらえますか?Swiftのエスケープクロージャの良い例は何ですか?

func performRequest(parameters: [String: String], completionHandler: (NSData?, NSError?) ->()) { 
    let request = NSMutableURLRequest(URL: url) 
    request.HTTPMethod = "POST" 
    request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(parameters, options: []) 
    request.setValue("application/json", forHTTPHeaderField: "Content-Type") 

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in 
     completionHandler(data, error) 
    } 
    task.resume() 
} 

そして、これがそうのように呼ばれている:

performRequest(["foo" : "bar"]) { data, error in 
    guard error == nil else { 
     print(error) 
     return 
    } 

    // now use data here 
} 

// Note: The `completionHandler` above runs asynchronously, so we 
// get here before the closure is called, so don't try to do anything 
// here with `data` or `error`. Any processing of those two variables 
// must be put _inside_ the closure above. 

このcompletionHandler

答えて

2

脱出閉鎖の例は、このようなネットワーク要求を開始するなど、いくつかの非同期タスク、中に完了ハンドラになりますNSURLSessionメソッドdataTaskWithRequestが非同期で実行されるため(つまり、即時に戻り、要求が終了したときに自身のクロージャが後で呼び出されるため)クロージャはエスケープされていると見なされます。

2

Swift 3では、パラメータはデフォルトでエスケープされません。

パラメータタイプの前に@escapingクロージャ属性を記述すると、関数が復帰した後にクロージャが呼び出されることが示されます。我々は@escaping属性を削除する場合

typealias Operation = (Data?) ->() 

func addToQueue(data: Data?, operation: @escaping Operation) { 
    OperationQueue.main.addOperation { 
     operation(data) 
    } 
} 

は、Xcodeのは

non-escaping parameter error message

+0

かなり明確な答え以下のエラーメッセージが表示されます、私の問題だったかを理解するのに役立ちました。私は3-4レベルのクロージャを持っていたので、正確に '@エスケープする 'がどこに置かれるべきかを理解することは難しかった。 – Jonauz

関連する問題