Как я мог создать функцию с обработчиком завершения в Swift?

Мне просто было любопытно, как я подойду к этому. Если бы у меня была функция, и я хотел бы, чтобы что-то произошло, когда она будет полностью выполнена, как бы я добавил это в функцию? Спасибо


person traw1233    schedule 22.05.2015    source источник
comment
На Youtube есть потрясающее видео:   -  person Bright Future    schedule 16.05.2016


Ответы (7)


Допустим, у вас есть функция загрузки для загрузки файла из сети, и вы хотите получать уведомление, когда задача загрузки завершена.

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

Надеюсь, это поможет.

person tounaobun    schedule 22.05.2015
comment
Это будет отлично работать, но больше из любопытства, мне было интересно, можете ли вы как-нибудь написать обработчик завершения в свою функцию. - person traw1233; 22.05.2015
comment
Привет, Floks, я хочу вызвать этот CompletionHandler из другой функции, как этого добиться? - person Himanshu jamnani; 23.05.2017
comment
любой пример для цели c - person Xcodian Solangi; 18.04.2018
comment
Когда я вызываю его другим классом, он не сеет параметр успеха обработчика завершения. - person Chandni; 13.07.2018

У меня возникли проблемы с пониманием ответов, поэтому я предполагаю, что у любого другого новичка, такого как я, может быть такая же проблема, как и у меня.

Мое решение делает то же самое, что и главный ответ, но, надеюсь, немного более ясное и легкое для понимания для новичков или людей, просто испытывающих проблемы с пониманием в целом.

Чтобы создать функцию с обработчиком завершения

func yourFunctionName(finished: () -> Void) {

     print("Doing something!")

     finished()

}

использовать функцию

     override func viewDidLoad() {

          yourFunctionName {

          //do something here after running your function
           print("Tada!!!!")
          }

    }

Ваш результат будет

Делать что-то

Тада !!!

Надеюсь это поможет!

person Cyril    schedule 08.01.2017

Простой пример:

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")
    }
})
person Bobby    schedule 10.04.2017

Для этой цели мы можем использовать закрытия. Попробуйте следующее

func loadHealthCareList(completionClosure: (indexes: NSMutableArray)-> ()) {
      //some code here
      completionClosure(indexes: list)
}

В какой-то момент мы можем вызвать эту функцию, как указано ниже.

healthIndexManager.loadHealthCareList { (indexes) -> () in
            print(indexes)
}

Перейдите по следующей ссылке для получения дополнительной информации о закрытии.

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html

person arango_86    schedule 20.01.2016

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 !!

person Lakhdeep Singh    schedule 20.12.2019

В дополнение к вышесказанному: можно использовать скользящее закрытие.

downloadFileFromURL(NSURL(string: "url_str")!)  { (success) -> Void in

  // When download completes,control flow goes here.
  if success {
      // download success
  } else {
    // download fail
  }
}
person Shrawan    schedule 27.08.2016

Я немного запутался в обработчиках завершения, сделанных на заказ. В вашем примере:

Допустим, у вас есть функция загрузки для загрузки файла из сети, и вы хотите получать уведомление, когда задача загрузки завершена.

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), не дожидаясь завершения загрузки кода?

person Heavy Breathing    schedule 06.01.2016
comment
В конце концов, что-то должно сидеть и ждать, пока запустится код, а не гигантская башня из асинхронных слонов, спущенных вниз. Асинхронный запуск означает наличие двух потоков. Один из них сидит и ждет, пока задание будет выполнено, другой продолжает и нет. Обработчик завершения вызывается или, по крайней мере, должен быть вызван по расписанию в конце потока, выполняющего работу. - person Crowman; 07.01.2016