1. Grand Central Dispatch

  • 멀티 코어 환경 / 멀티 스레드 환경에서 최적화된 프로그래밍을 할 수 있는 기술
  • 개발자가 직접 코어와 스레드를 관리하지 않아도 시스템에서 관리

2. DispatchQueue

  • DispatchQueue에 작업을 넘겨주면 알아서 동작하는 것
  • DispatchQueue는 GCD를 사용하기 위한 대기열
  • 이 대기열에 작업을 추가하면 시스템은 알아서 스레드를 관리 및 작업을 처리
  • DispatchQueue는 선입 선출 (first in / first out)으로 작업을 처리
  • DispatchQueue에 작업을 넘길 때는 단일스레드(Serial) / 다중스레드(Concurrency), 동기 / 비동기로 작업을 처리할지 2가지를 정해주어야 한다.

3. DispatchQueue - Serial / Concurrency

  • Serial - 단일 스레드에서만 작업처리
  • Concurrency - 다중 스레드에서 작업 처리
  • DispatchQueue 초기화시 attribute값을 .concurrent라고 설정하지 않으면 기본 serial 처리
// Serial Queue
DispatchQueue(labal: "Serial")
DispatchQueue.main
// main은 적역적 사용되는 Serial DispatchQueue

// Concurrent Queue
DispatchQueue(label: "Concurrent", attributes: .concurrent)
DispatchQueue.global()
Main Thread
- 앱의 기본이 되는 스레드
- 앱이 실행되는 동안 늘 메모리에 올라와 있는 기본 스레드
메인 스레드에서부터 필요한 만큼의 스레드가 파생

특징:
- 전역적 사용
- global 스레드들과는 다르게 Run loop가 자동으로 설정되고 실행
- UI 작업은 메인 스레드에서만 작업 가능

4. DispatchQueue - main / global()

  • DispatchQueue.main / DispatchQueue.global()은 이미 만들어져 있는 queue로 각각 serial / concurrent queue
  • main은 일반적인 serial queue와는 달리 앱이 실행되어 있는 동안 늘 메모리에 올라와 있고 전역적으로 사용 가능한 queue
  • main에 작업을 추가하면 main 스레드에서 작업을 처리
  • global에 작업을 추가하면 새로운 스레드를 만들어 그 위에서 작업을 처리
  • global 스레드는 main 스레드가 아닌 작업을 처리하기 위해 발생한 스레드들의 총칭
  • global()이 호출되면 작업을 처리하기위해 메모리에 올라왔다가 작업이 끝나고 나면 메모리에서 제거

5. DispatchQueue - 동기 / 비동기

  • serial / concurrent queue를 정해주었다면 동기 / 비동기 처리를 정해주면 된다.
// 동기
DispatchQueue.main.sync {}
DispatchQueue.global().sync {}

// 비동기
DispatchQueue.main.async {}
DispatchQueue.global().async {}
  • 하지만 main.sync를 직접적으로 호출하면 deadlock / 교착상태에 빠지게됨

6. DispatchQueue - deadlock

  • block wait : 코드 블록이 처리되기 전까지 다음코드로 넘어가지 않는 것
  • main.sync 호출시 main thread는 코드블록이 수행되기를 기다려야함
  • 이때 sync의 코드 블록 역시 멈춰버리게 되는데 main thread에서 실행되고 있던 코드이기 때문
  • 따라서 main thread는 sync 종료를, sync는 main thread의 block wait가 끝나기를 기다리는 상태가 발생
  • main thread에서 main.sync를 호출하지 않는 다면 에러없이 동작

DispatchQueue.global().async {
    DispatchQueue.main.sync {
        for _ in 1...5 {
            print("😀😀😀😀😀")
            sleep(1)
        }
    }
}

for _ in 1...5 {
    print("🥶🥶🥶🥶🥶")
    sleep(2)
}

7. DispatchWorkItem

  • DispatchWorkItem: DispatchQueue 코드 블록을 캡슐화 해주는 기능
  • 정의된 DispatchWorkItem는 sync / async 메서드의 execute 파라미터를 통해 전달
let red = DispatchWorkItem {
    for _ in 1...5 {
        print("🥵🥵🥵🥵🥵")
        sleep(1)
    }
}

DispatchQueue.main.async(execute: red)

8. asyncAfter

  • async 메서드를 원하는 시간에 호출해줄 수 있는 메서드
  • 지금으로 부터 5초 후 작업 실행 코드
DispatchQueue.global().asyncAfter(deadline: .now() + 5, execute: yellow)
DispatchQueue.global().asyncAfter(wallDeadline: .now() + 5, excute: blue)
  • deadline : 5초를 카운트해서 작업 시작
  • wallDeadline : 현재 시각으로부터 5초후 작업 실행

9. asyncAndWait

  • 비동기 작업이 끝나는 시점을 대기
  • 비동기 처리되는 어떤 동작이 끝나기를 의도적으로 기다려야할 때 사용
DispatchQueue.global().asyncAndWait(execute: yellow)
print("Finished!")
profile
Wooyo의 개발 블로그

0개의 댓글