GCD에 관하여 - 3

2023. 3. 12. 21:05IOS

반응형

DispatchQueue.Attributes

convenience init(
    label: String,
    qos: DispatchQoS = .unspecified,
    attributes: DispatchQueue.Attributes = [],
    autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = .inherit,
    target: DispatchQueue? = nil
)
  • DispatchQueue를 커스텀하기 위해서 init을 사용하면 attributes라는 항목이 있다.
  • 이 부분을 설정을 하지 않으면 기본적으로 Serial이 되며, Concurrency를 넣어줄 경우 동시성 큐가 된다.
  • 다만, 특이한 항목이 하나 더 있다.

initiallyInactive

let queue = DispatchQueue(label: "QueueLabel")

queue.async{ 
    print("시작")
}
  • 해당 큐를 브레이크 포인트를 걸 경우 async의 코드가 실행되는 순간 같이 코드가 실행된다.
let queue = DispatchQueue(label: "QueueLabel", attributes: .initiallyInactive)

queue.async{ 
    print("시작")
}
  • 위 코드를 실행할 경우 굳이 브레이크포인트를 걸지 않아도 실행이 되지 않는다.
  • 이유는 initiallyInactive 큐 자체에 코드블록을 추가 시켜도 실행 하지 않는다.
  • 이를 실행하기 위해서는 active메소드를 사용하여야한다.
queue.activate()

DispatchGroup

  • DispatchGroup | Apple Developer Documentation
  • 작업들의 그룹이라고 말할 수 있으며, 비동기에 대한 추적을 할 수 있게 만들어준다.
  • 그룹에 대한 작업들이 전부 완료될때까지 completion handler를 통해 기다려 줄 수도 있다.

  • 기본적으로 초기화 함수 인자가 없다.
  • 인스턴스를 바로 생성하여 추가하고 사용을 하게끔 만들어져있다.
let group = DispatchGroup()
let item = DispatchWorkItem {
    print("시작")
    Thread.sleep(forTimeInterval: 2)
    print("끝")
}


DispatchQueue.main.async(group: group, execute: item)
DispatchQueue.global().async(group: group, execute: item)
  • 위와 같이 사용 가능하며, 혹은 enterleave메소드를 통하여 DispatchGroup이 해당 영역에서 추가된다라는것을 명시적으로 보여줄 수 있다.
group.enter()
DispatchQueue.main.async(group: group, execute: item)
DispatchQueue.global().async(group: group, execute: item)
group.leave()

notify

group.notify(queue: .global()) {
    print("코드 종료")
}
  • 위 인자의 queue는 모든 작업이 끝난 이후 뒤 코드블록이 실행 될 큐를 의미한다.

wait

  • wait는 해당 모든 작업이 끝나기를 기다리며, notify와는 다르게 별도의 코드블럭을 실행하지 않는다.
  • 인자로 timeoutwallTimeout을 받는데 해당 시간이 지난 후에도 작업이 끝나지 않았다면 정지하고 다음 코드들을 실행한다.
let group = DispatchGroup()
let item = DispatchWorkItem {
    print("시작")
    Thread.sleep(forTimeInterval: 5)
    print("끝")
}

group.enter()
DispatchQueue.global().async(group: group, execute: item)
DispatchQueue.global().async(group: group, execute: item)
group.leave()

group.wait(timeout: .now() + 2)
print("종료!!!")
// 시작
// 시작
// 작업 끝
// 끝
// 끝
  • 위 코드를 실행할 경우 2초가 지났기 때문에 이후 코드가 실행되고 나머지 작업이 처리 된 모습을 보여준다.
반응형