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