작업이 완료될 때까지 기다리는 중
DispatchQueue의 작업이 완료될 때까지 코드를 대기시키려면 어떻게 해야 합니까?Completion Handler 같은 것이 필요합니까?
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에 글을 쓰고 있습니다.
의 비동기성을 숨겨야 하는 경우myFunction호출자로부터, 사용DispatchGroup이를 달성하기 위해 s.그렇지 않으면 완료 블록을 사용합니다.아래 두 가지 모두에 대한 표본을 찾습니다.
디스패치 그룹 샘플
그룹이 종료될 때 알림을 받을 수 있습니다.enter()그리고.leave()통화 균형 조정:
func myFunction() {
var a = 0
let group = DispatchGroup()
group.enter()
DispatchQueue.main.async {
a = 1
group.leave()
}
// does not wait. But the code in notify() is executed
// after enter() and leave() calls are balanced
group.notify(queue: .main) {
print(a)
}
}
또는 기다릴 수 있습니다.
func myFunction() {
var a = 0
let group = DispatchGroup()
group.enter()
// avoid deadlocks by not using .main queue here
DispatchQueue.global(qos: .default).async {
a = 1
group.leave()
}
// wait ...
group.wait()
print(a) // you could also `return a` here
}
참고:group.wait()현재 대기열을 차단합니다(사용자의 경우 주 대기열을 차단합니다).dispatch.async교착 상태를 방지하기 위해 다른 대기열(위 샘플 코드와 같은)에 있습니다.
완성 블록 샘플
func myFunction(completion: @escaping (Int)->()) {
var a = 0
DispatchQueue.main.async {
let b: Int = 1
a = b
completion(a) // call completion after you have the result
}
}
// on caller side:
myFunction { result in
print("result: \(result)")
}
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를 사용하여 작업을 완료할 때 completionHandler를 사용하려면 다음을 사용할 수 있습니다.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
}
솔루션의 신속한 5가지 버전
func myCriticalFunction() {
var value1: String?
var value2: String?
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)")
}
디스패치 그룹 사용
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.5+에서는 메인 스레드로 전송된 폐쇄에서 값을 반환할 수 있는 Swift Concurrency를 활용할 수 있습니다.
func myFunction() async {
var a : Int?
a = await MainActor.run {
let b = 3
return b
}
print(a)
}
Task {
await myFunction()
}
스위프트 4
이러한 상황에서 비동기 기능을 사용할 수 있습니다.사용할 때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!)
}
}
}
어찌된 일인지 위의 dispatchGroup enter() 및 leave() 명령이 제 경우에는 작동하지 않았습니다.
하지만 배경 스레드에서 잠시 동안 sleep(5)을 사용하는 것은 저에게 효과가 있었습니다.다른 사람에게 도움이 되고 내 다른 스레드에 방해가 되지 않을 경우를 대비하여 여기를 떠나는 것.
언급URL : https://stackoverflow.com/questions/42484281/waiting-until-the-task-finishes
'programing' 카테고리의 다른 글
| 데이터베이스 목록을 로드하지 못했습니다. (0) | 2023.05.06 |
|---|---|
| iOS 상태 표시줄 높이를 프로그래밍 방식으로 가져오는 방법 (0) | 2023.05.01 |
| 문자열 리터럴과 문자열을 일치시키는 방법은 무엇입니까? (0) | 2023.05.01 |
| 오류: "설치 가능한 ISAM을 찾을 수 없습니다." (0) | 2023.05.01 |
| C#에서 const와 read only의 차이점은 무엇입니까? (0) | 2023.05.01 |