DispatchQueue의 작업이 완료 될 때까지 코드를 기다리게하려면 어떻게해야합니까? CompletionHandler 또는 무언가가 필요합니까?
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
}
저는 Xcode 8.2를 사용하고 있으며 Swift 3로 작성하고 있습니다.
답변
DispatchGroup
이를 위해 s를 사용하십시오 . 그룹 enter()
과 leave()
통화가 균형을 이룰 때 알림을받을 수 있습니다 .
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)
}
}
또는 기다릴 수 있습니다.
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) // you could also `return a` here
}
참고 : group.wait()
현재 대기열 (아마도 귀하의 경우 기본 대기열)을 차단하므로 교착 상태dispatch.async
를 피하기 위해 다른 대기열 (위 샘플 코드와 같음)에 있어야합니다 .
답변
Swift 3에서는 DispatchQueue
하나의 작업 을 완료 할 때 완료 핸들러가 필요하지 않습니다 . 또한 다양한 방법으로 목표를 달성 할 수 있습니다.
한 가지 방법은 다음과 같습니다.
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)")
루프가 끝날 때까지 기다릴 것이지만이 경우 메인 스레드가 차단됩니다.
다음과 같이 동일한 작업을 수행 할 수도 있습니다.
let myGroup = DispatchGroup()
myGroup.enter()
//// Do your task
myGroup.leave() //// When your task completes
myGroup.notify(queue: DispatchQueue.main) {
////// do your remaining work
}
마지막으로 작업이 DispatchQueue를 사용하여 완료 될 때 완료 핸들러를 사용하려면 DispatchWorkItem
.
다음은 사용 방법의 예입니다 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
}
답변
디스패치 그룹 사용
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.
답변
솔루션의 Swift 5 버전
func myCriticalFunction () {var value1 : 문자열? var value2 : 문자열?
let group = DispatchGroup()
group.enter()
//async operation 1
DispatchQueue.global(qos: .default).async {
// Network calls or some other async task
value1 = //out of async task
group.leave()
}
group.enter()
//async operation 2
DispatchQueue.global(qos: .default).async {
// Network calls or some other async task
value2 = //out of async task
group.leave()
}
group.wait()
print("Value1 \(value1) , Value2 \(value2)")
}
답변
스위프트 4
이러한 상황에 Async Function을 사용할 수 있습니다. 를 사용 DispatchGroup()
하면 가끔 교착 상태 가 발생할 수 있습니다.
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!)
}
}
}