Как я могу создать функцию с обработчиком завершения в Swift?
Мне было просто любопытно, как я подойду к этому. Если бы у меня была функция, и я хотел, чтобы что-то произошло, когда она была полностью выполнена, как бы я добавил это в функцию? Спасибо
9 ответов
Допустим, у вас есть функция загрузки для загрузки файла из сети, и вы хотите получать уведомления о завершении задачи загрузки.
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
}
})
Надеюсь, поможет.:-]
У меня были проблемы с пониманием ответов, поэтому я предполагаю, что любой другой новичок, такой как я, может иметь ту же проблему, что и я
Мое решение делает то же самое, что и верхний ответ, но, надеюсь, будет немного более ясным и понятным для новичков или людей, которые просто не понимают в целом.
Чтобы создать функцию с обработчиком завершения
func yourFunctionName(finished: () -> Void) {
print("Doing something!")
finished()
}
использовать функцию
override func viewDidLoad() {
yourFunctionName {
//do something here after running your function
print("Tada!!!!")
}
}
Ваш вывод будет
Doing something
Tada!!!
Надеюсь это поможет!
Простой пример 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)
}
Как это использовать:
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")
}
})
Swift 5.0 +, простой и короткий
пример:
Стиль 1
func methodName(completionBlock: () -> Void) {
print("block_Completion")
completionBlock()
}
Стиль 2
func methodName(completionBlock: () -> ()) {
print("block_Completion")
completionBlock()
}
Использование:
override func viewDidLoad() {
super.viewDidLoad()
methodName {
print("Doing something after Block_Completion!!")
}
}
Выход
block_Completion
Что-то делать после Block_Completion!!
Мы можем использовать затворы для этой цели. Попробуйте следующее
func loadHealthCareList(completionClosure: (indexes: NSMutableArray)-> ()) {
//some code here
completionClosure(indexes: list)
}
В какой-то момент мы можем вызвать эту функцию, как указано ниже.
healthIndexManager.loadHealthCareList { (indexes) -> () in
print(indexes)
}
Пожалуйста, перейдите по следующей ссылке для получения дополнительной информации о замыканиях.
Если вам нужны значения результата в обработчике завершения, рекомендуется включить метки с символами подчеркивания, например:
func getAccountID(account: String, completionHandler: (_ id: String?, _ error: Error?) -> ()) {
// Do something and return values in the completion handler
completionHandler("123", nil)
}
... потому что, когда вы вводите эту функцию, Xcode автоматически заполняет метки значений результата, например:
getAccountID(account: inputField.stringValue) { id, error in
}
Я немного запутался в пользовательских обработчиках завершения. В вашем примере:
Допустим, у вас есть функция загрузки для загрузки файла из сети, и вы хотите получать уведомления о завершении задачи загрузки.
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)
}
Ваш // download code
все равно будет работать асинхронно. Почему код не идет прямо на ваш let flag = true
а также completion Handler(success: flag)
не дожидаясь окончания загрузки кода?
В дополнение к вышесказанному: можно использовать трейлинг-стоп.
downloadFileFromURL(NSURL(string: "url_str")!) { (success) -> Void in
// When download completes,control flow goes here.
if success {
// download success
} else {
// download fail
}
}
//MARK: - Define
typealias Completion = (_ success:Bool) -> Void
//MARK: - Create
func Call(url: NSURL, Completion: Completion) {
Completion(true)
}
//MARK: - Use
Call(url: NSURL(string: "http://")!, Completion: { (success) -> Void in
if success {
//TRUE
} else {
//FALSE
}
})