2016-03-27 3 views
6

Ich lese das Swift Programmiersprache Handbuch und es erwähnt eine ausweichende Schließung. In Bezug auf das Schließen von Schließungen weiß ich nicht, was sie damit meinen, "die Schließung wird als ein Argument für die Funktion übergeben, aber wird aufgerufen, nachdem die Funktion zurückkehrt." Könnte jemand ein Beispiel für fliehende Schließungen geben?Was ist ein gutes Beispiel für eine Flucht Schließung in Swift?

Antwort

2

Ein Beispiel für eine Flucht Schließung würde die Abschluss-Handler in einiger asynchronen Aufgabe sein, wie eine Netzwerkanfrage initiiert:

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() 
} 

Und wie so genannt wird:

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. 

Diese completionHandler Es wird angenommen, dass der Abschluss besteht, da NSURLSession Methode dataTaskWithRequest asynchron ausgeführt wird (dh es wird sofort zurückgegeben und seine eigene Schließung wird später aufgerufen, wenn die Anforderung abgeschlossen ist).

2

In Swift 3 werden die Verschlussparameter standardmäßig deaktiviert.

Wir müssen @escaping Closure-Attribut vor dem Parametertyp schreiben, um anzuzeigen, dass die Schließung aufgerufen wird, nachdem die Funktion zurückgibt.

typealias Operation = (Data?) ->() 

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

Wenn wir @escaping Attribut entfernen, Xcode die Fehlermeldung unter

non-escaping parameter error message

+0

Ganz klare Antwort zeigen, geholfen zu verstehen, wo mein Problem war. Ich hatte 3-4 Level-Schließungen, so war es schwer zu verstehen, wo genau '@ Escaping' platziert werden sollte. – Jonauz