Sto leggendo il manuale del linguaggio di programmazione Swift e menziona una chiusura di escape. Per quanto riguarda le chiusure in fuga, non so cosa intendano con "la chiusura viene passata come argomento alla funzione, ma viene chiamata dopo che la funzione ritorna". Qualcuno potrebbe fornire un esempio su chiusure di fuga?Qual è un buon esempio di chiusura di una fuga in Swift?
risposta
Un esempio di una chiusura in fuga sarebbe il gestore di completamento in qualche operazione asincrona, come ad esempio l'avvio di una richiesta di rete:
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()
}
e questo è chiamato in questo modo:
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.
Questo completionHandler
chiusura è considerata come fuga in quanto il metodo NSURLSession
dataTaskWithRequest
viene eseguito in modo asincrono (ovvero restituisce immediatamente e la sua chiusura verrà richiamata in seguito al termine della richiesta).
In Swift 3 i parametri di chiusura diventano senza escape per impostazione predefinita.
Abbiamo bisogno di scrivere l'attributo @escaping
prima del tipo di parametri per indicare che la chiusura viene chiamata dopo che la funzione è tornata.
typealias Operation = (Data?) ->()
func addToQueue(data: Data?, operation: @escaping Operation) {
OperationQueue.main.addOperation {
operation(data)
}
}
Se togliamo attributo @escaping
, Xcode mostrerà il seguente messaggio di errore
risposta Abbastanza chiaro, ha aiutato a capire dove era il mio problema. Avevo 3-4 livelli di chiusura, quindi era difficile capire dove esattamente "@ escaping" dovrebbe essere posizionato. – Jonauz