Risposte:
Supponiamo che tu abbia una funzione di download per scaricare un file dalla rete e desideri essere avvisato quando l'attività di download è terminata.
typealias CompletionHandler = (success:Bool) -> Void
func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {
// download code.
let flag = true // true if download succeed,false otherwise
completionHandler(success: flag)
}
// How to use it.
downloadFileFromURL(NSURL(string: "url_str")!, { (success) -> Void in
// When download completes,control flow goes here.
if success {
// download success
} else {
// download fail
}
})
Spero che sia d'aiuto.
Ho avuto problemi a capire le risposte, quindi presumo che qualsiasi altro principiante come me potrebbe avere lo stesso problema come me.
La mia soluzione è uguale alla risposta principale, ma si spera un po 'più chiara e facile da capire per i principianti o per le persone che hanno difficoltà a capire in generale.
Per creare una funzione con un gestore di completamento
func yourFunctionName(finished: () -> Void) {
print("Doing something!")
finished()
}
per utilizzare la funzione
override func viewDidLoad() {
yourFunctionName {
//do something here after running your function
print("Tada!!!!")
}
}
La tua uscita sarà
Facendo qualcosa
Tada !!!
Spero che questo ti aiuti!
Semplice esempio di Swift 4.0:
func method(arg: Bool, completion: (Bool) -> ()) {
print("First line of code executed")
// do stuff here to determine what you want to "send back".
// we are just sending the Boolean value that was sent in "back"
completion(arg)
}
Come usarlo:
method(arg: true, completion: { (success) -> Void in
print("Second line of code executed")
if success { // this will be equal to whatever value is set in this method call
print("true")
} else {
print("false")
}
})
Possiamo usare le chiusure per questo scopo. Prova quanto segue
func loadHealthCareList(completionClosure: (indexes: NSMutableArray)-> ()) {
//some code here
completionClosure(indexes: list)
}
Ad un certo punto possiamo chiamare questa funzione come indicato di seguito.
healthIndexManager.loadHealthCareList { (indexes) -> () in
print(indexes)
}
Fare riferimento al seguente collegamento per ulteriori informazioni sulle chiusure .
Swift 5.0 +, semplice e breve
esempio:
Stile 1
func methodName(completionBlock: () -> Void) {
print("block_Completion")
completionBlock()
}
Stile 2
func methodName(completionBlock: () -> ()) {
print("block_Completion")
completionBlock()
}
Uso:
override func viewDidLoad() {
super.viewDidLoad()
methodName {
print("Doing something after Block_Completion!!")
}
}
Produzione
block_Completion
Fare qualcosa dopo Block_Completion !!
Sono un po 'confuso riguardo ai gestori di completamento personalizzati. Nel tuo esempio:
Supponiamo che tu abbia una funzione di download per scaricare un file dalla rete e desideri essere avvisato quando l'attività di download è terminata.
typealias CompletionHandler = (success:Bool) -> Void
func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {
// download code.
let flag = true // true if download succeed,false otherwise
completionHandler(success: flag)
}
Il tuo // download code
verrà comunque eseguito in modo asincrono. Perché il codice non andrebbe direttamente al tuo let flag = true
e completion Handler(success: flag)
senza attendere che il codice di download sia terminato?