grand example dispatchqueue dispatch_async central async swift multithreading asynchronous swift3 grand-central-dispatch

swift - example - Esperando hasta que termine la tarea



nsoperationqueue swift 3 example (4)

¿Cómo podría hacer que mi código espere hasta que finalice la tarea en DispatchQueue? ¿Necesita algún CompletionHandler o algo?

func myFunction() { var a: Int? DispatchQueue.main.async { var b: Int = 3 a = b } // wait until the task finishes, then print print(a) // - this will contain nil, of course, because it // will execute before the code above }

Estoy usando Xcode 8.2 y escribo en Swift 3.


En Swift 3, no es necesario un controlador de finalización cuando DispatchQueue finaliza una tarea. Además, puede lograr su objetivo de diferentes maneras

Una forma es esta.

var a: Int? let queue = DispatchQueue(label: "com.app.queue") queue.sync { for i in 0..<10 { print("Ⓜ️" , i) a = i } } print("After Queue /(a)")

Esperará hasta que finalice el bucle, pero en este caso su cadena de correo se bloqueará.

También puedes hacer lo mismo así

let myGroup = DispatchGroup() myGroup.enter() //// Do your task myGroup.leave() //// When your task completes myGroup.notify(queue: DispatchQueue.main) { ////// do your remaining work }

Una última cosa. Si desea usar completeHandler cuando su tarea se complete con DispatchQueue, puede usar DispatchWorkItem .

Aquí hay un ejemplo de cómo usar DispatchWorkItem

let workItem = DispatchWorkItem { // Do something } let queue = DispatchQueue.global() queue.async { workItem.perform() } workItem.notify(queue: DispatchQueue.main) { // Here you can notify you Main thread }


Usar grupo de despacho

dispatchGroup.enter() FirstOperation(completion: { _ in dispatchGroup.leave() }) dispatchGroup.enter() SecondOperation(completion: { _ in dispatchGroup.leave() }) dispatchGroup.wait() //Waits here on this thread until the two operations complete executing.


Use DispatchGroup s para lograr esto. Puede recibir una notificación cuando las llamadas enter() y leave() estén equilibradas:

func myFunction() { var a: Int? let group = DispatchGroup() group.enter() DispatchQueue.main.async { a = 1 group.leave() } // does not wait. But the code in notify() gets run // after enter() and leave() calls are balanced group.notify(queue: .main) { print(a) } }

o puedes esperar:

func myFunction() { var a: Int? let group = DispatchGroup() group.enter() // avoid deadlocks by not using .main queue here DispatchQueue.global(attributes: .qosDefault).async { a = 1 group.leave() } // wait ... group.wait() print(a) }

Nota : group.wait() bloquea la cola actual (probablemente la cola principal en su caso), por lo que debe dispatch.async en otra cola (como en el código de muestra anterior) para evitar un punto muerto .


Swift 4

Puede usar la función asíncrona para estas situaciones. Cuando usa DispatchGroup() , a veces puede producirse un punto muerto .

var a: Int? @objc func myFunction(completion:@escaping (Bool) -> () ) { DispatchQueue.main.async { let b: Int = 3 a = b completion(true) } } override func viewDidLoad() { super.viewDidLoad() myFunction { (status) in if status { print(self.a!) } } }