iOS/Swift이론

Swift의 비동기 처리

Sweetft 2023. 1. 8. 15:11

※해당 글은 Swift 비동기에 관한 다른 블로그 글들을 보고 공부 목적으로 정리하였습니다. 더 자세한 정보를 원할 시 하단의 출처를 보시고 해당 글들을 참고하시길 바랍니다!!

 

Sync vs Async

Sync(동기)

  • 요청과 응답이 동시에 일어남
  • 코드 작성 순서대로 호출
  • 주어진 작업이 완료될 때 까지 다음 작업으로 넘어가지 않음

Async(비동기)

  • 요청과 응답이 동시에 일어나지 않는 방식. 요청하면 상황에 따라 응답(하지 않을 수도 있음)
  • 주어진 작업의 완료 여부와 관계 없이 작업 전달 후 바로 다음 작업으로 넘어감

 

Serial vs Concurrent

Serial(직렬)

  • 순차 진행
  • 할 일을 하나의 스레드에 차곡차곡 순서대로 쌓는 것
  • DisaptchQueue.main()

Concurrent(동시)

  • 동시 작업 수행
  • 할 일을 여러 스레드에 마구잡이로 분산 배치하는 것
  • DispatchQueue.global()

 

4가지 조합

1. Serial 큐 + sync

DispatchQueue.main.sync{}

현재 iOS 프로그래밍에서는 사용 금지(deadlock 발생)

 

2. Serial 큐 + async

DispatchQueue.main.async{}

메인 스레드로 작업을 전달하지만 완료를 기다리지 않는다.

Serial 큐이기에 작업을 하나의 스레드에 작업을 순서대로 전달하고 async 메서드이므로 완료를 기다리지 않고 곧 바로 다른 작업을 진행시킨다. 주로 ui 작업

 

3. Concurrent 큐 + sync

DispatchQueue.global().sync{}

다른 여러 스레드로 작업 분산 배치, 배치한 작업들이 모두 완료될 때 까지 이전 스레드를 블락하고 기다린다.

Concurrent 큐니까 작업을 분산 배치하고 sync 메서드이므로 완료를 기다리는 것. 자주 사용되지는 않는다.

 

4. Concurrent 큐 + async

DispatchQueue.global().async{}

작업을 다른 여러 스레드로 분산 배치하되 완료를 기다리지는 않는다.

Concurrent 큐니까 작업을 분산 배치하고, async 메서드이므로 완료를 기다리지 않는다. 주로 api 통신 등에 사용

 

 

Swift에서의 비동기 실행

  • 가장 대표적인 처리 방식은 GCD(Grand Central Dispatch)라는 API
  • GCD : Queue(Dispatch Queue)에 작업을 보내면 이에 맞춰 스레드를 적절히 생성해 분배해주는 역할
  • 즉, Dispatch Queue에 task 추가하면 GCD가 task에 맞춰 스레드를 자동으로 생성해 실행하고, task가 완료되면 스레드를 제거하는 일련의 과정 관리 //DispatchQueue.global().async{//task}
  • DispatchQueue.global().async{//task} //여기서 closure 내부의 task는 하나의 작업 그룹이므로 이는 순차적으로 처리된다.
  • sync,async는 task를 보낸 시점에서 작업 완료를 기다릴지 말지를 다루는 것이며, serial,concurrent는 queue에 보내진 작업을 하나의 스레드에만 보낼 건지, 여러 스레드에 보낼건 지를 다룸

GlobalQueue는 Concurrent의 특성. 해당 큐는 여러 개의 스레드로 task를 분산시. 또한 해당 큐는 DispatchQueue.global(qos: .utility).async[}와 같이 qos(Quality of Service)를 지정함으로 작업의 중요도를 정해줄 수 있다.

 

QoS의 종류 6가지

  • userInteractive: 사용자와 직접 상호작용하는 작업(aka.ui업데이트,애니메이션)
  • userInitiated : 클릭 시 작업 수행하는 것과 같은 즉각적 결과가 필요한 작업(aka.저장된 문서 열기)
  • default : 기본값
  • utility: progress bar과 함께 길게 실행되는 작업(aka.데이터 다운로드)
  • background: 유저가 직접적으로 인지하지 않는 등 시가이 덜 중요한 작업 (aka. 동기화 및 백업)
  • unspecified : qos 정보 없음 (aka.거의 사용X)

 

CustomQueue: 사용자가 직접 만드는 큐이므로 디폴트로는 Serial 특성이지만 Concurrent로 변경 가능, QoS 설정도 가능

  • 생성 시 매개변수 label을 붙이면 customQueue가 되며 추자적으로 attributes나 qos등 매개변수 사용하면 특성과 qos 설정 변경도 가능
  • Ex. let custom = DispatchQueue(label: “something”, qos: .background, attributes: .concurrent)

 

Async, Await은 뭐야???

  • 기존 비동기 처리 방식은 DispatchQueue나 completionHandler 사용해 처리했지만, 더욱 편하게 비동기 처리할 수 있는 문법!
  • Async 키워드는 비동기 task 정의 (위에 더 자세한 설명), throws를 같이 쓸 수 있음, 프로토콜에서도 요구 가능
  • Await 키워드는 비동기 함수의 실행을 동기화 시킴, 현재 스레드에서 해당 비동기 함수의 실행이 끝날 때 까지 대기, await은 블로킹(blocking) 유발하기 때문에 async로 마크된 비동기 함수 내부에서만 사용 가능.
Func practiceWhat() async {
…코드1…
Try? Await practice()
…코드2…
}
  • 여기서 코드1 실행 중 practice() 실행 시, 해당 작업이 끝날 때 까지 코드2는 실행되지 않음
  • 한 번에 여러 작업 동시에 실행하고자 할 때 async-let  문법의 코드를 작성해 병렬 수행 할 수 있다.

 

 

[출처]

 

https://velog.io/@wnsxor1993/Swift%EC%9D%98-%EB%8F%99%EA%B8%B0%EC%99%80-%EB%B9%84%EB%8F%99%EA%B8%B0

 

https://medium.com/@goehd2538/ios%EC%9D%98-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC%EB%B0%A9%EC%8B%9D-65aa81aad0f9

 

https://ios-development.tistory.com/958

 

https://beenii.tistory.com/202