In attesa fino al termine dell’attività

Come posso rendere il mio codice in attesa fino a quando non termina l’attività in DispatchQueue? Ha bisogno di qualche CompletionHandler o qualcosa del genere?

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 } 

Sto usando Xcode 8.2 e sto scrivendo in Swift 3.

Utilizzare DispatchGroup per ottenere ciò. Puoi ricevere una notifica quando le chiamate enter() e leave() sono bilanciate:

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

oppure puoi aspettare (e tornare):

 func myFunction() -> Int? { 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() // ... and return as soon as "a" has a value return a } 

Nota : group.wait() blocca la coda corrente (probabilmente la coda principale nel tuo caso), quindi devi inviare.async su un’altra coda (come nel codice di esempio precedente) per evitare un deadlock .

In Swift 3, non è necessario per il gestore di completamento quando DispatchQueue termina un’attività. Inoltre puoi raggiungere il tuo objective in diversi modi

Un modo è questo.

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

Attenderà fino al termine del ciclo, ma in questo caso il thread della posta verrà bloccato.

Puoi anche fare la stessa cosa in questo modo

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

Un'ultima cosa. Se si desidera utilizzare completionHandler quando l'attività viene completata utilizzando DispatchQueue, è ansible utilizzare DispatchWorkItem .

Ecco un esempio di come usare 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 } 

Usa il gruppo di spedizione

  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.