일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- retain cycle
- 면접을 위한 CS전공 지식 노트
- ReferceCycle
- Input Output
- CoreData
- coremotion
- Reference Cycle
- CarouselCollectionview
- 양궁대회
- @escaping
- UserDefaults
- tableview section별 다른 cell적용
- class struct
- UIKit
- til
- 면접을 위한 CS 전공 지식 노트 Tree
- firebase
- TableView
- Value Type Reference Type
- 롤케이크 자르기
- SWIFT
- wil
- TableView Section
- 강한 참조 순환
- Carousel CollectionView
- NavigationSearchBar
- 프로그래머스
- 자료구조
- Array vs Linked List
- 테이블뷰 나누기
- Today
- Total
개발하는 동글 :]
[TIL],[Swift],[DispatchQueue] 본문
1. DispatchQueue?
공식문서의 내용을 살펴보면 DispatchQueue는 앱의 기본 스레드 또는 백그라운드 스레드에서 작업의 동기 또는 비동기 실행을 관리하는 Class이다. 이 것을 확인해 보기 위해 아래의 두 개의 메서드를 만들어서 확인해 보자.
func shortWork(_ num:Int){
DispatchQueue.global().async {
print("shortWork[\(num)]Start")
print("1")
print("2")
print("3")
print("4")
print("5")
print("shortWork[\(num)]End")
}
}
func longWork(_ num:Int){
DispatchQueue.global().async {
print("longWork[\(num)]Start")
sleep(1)
print("longWork[\(num)]End")
}
}
2. DispatchQueue의 동작 순서
2.1 DispatchQueue 내부의 동작 순서
override func viewDidLoad() {
super.viewDidLoad()
self.shortWork(1)
}
위의 코드를 실행하였을 때의 결과이다.
이것으로 알 수 있는 것은 DispatchQueue의 내부는 동기적으로 동작하는 것을 알 수 있다.
2.2 외부에서의 DispatchQueue의 동작 순서
override func viewDidLoad() {
super.viewDidLoad()
self.longWork(1)
self.longWork(2)
self.longWork(3)
self.longWork(4)
self.longWork(5)
}
위의 코드를 실행해 보았을 때의 결과를 확인해 보면 DispatchQueue는 외부에서 동작순서는 보장받지 못한다는 것을 알 수 있다.
3. 직렬큐(Serial),동시큐(Concurrent)
3.1. 직렬큐(Serial)
그럼 비동기적으로 처리하면서 순서를 보장받고 싶다면 어떡해야 할까?
아래의 코드처럼 직렬큐를 만들어 사용하면 된다.
let serialQueue = DispatchQueue(label: "some") //직렬큐 생성
override func viewDidLoad() {
super.viewDidLoad()
serialQueue.async {
self.shortWork(1)
}
serialQueue.async {
self.shortWork(2)
}
serialQueue.async {
self.shortWork(3)
}
}
func shortWork(_ num:Int){
print("shortWork[\(num)]Start")
print("shortWork[\(num)]End")
}
결과를 위의 global과 비교를 해본다면 이처럼 직렬큐를 사용하였을 때 같은 직렬큐 내부에서는 동기적으로 처리가 되는 것을 확인할 수 있다.
3.2 동시큐(Concurrent)
그럼 이번에는 초반의 예시와 같이 global이란 큐를 사용하여 같은 코드를 비교해 보자
let concurrentQueue = DispatchQueue.global()
override func viewDidLoad() {
super.viewDidLoad()
concurrentQueue.async {
self.shortWork(1)
}
concurrentQueue.async {
self.shortWork(2)
}
concurrentQueue.async {
self.shortWork(3)
}
}
func shortWork(_ num:Int){
print("shortWork[\(num)]Start")
print("shortWork[\(num)]End")
}
그럼 이전과 동일하게 순서가 보장받지 않는 상태가 된다.
이러한 코드와 결과를 통해 직렬큐와 동시큐의 차이를 알 수 있다.
그렇다면 모두가 다른 직렬큐를 사용하여 실행하였을 때에는 어떻게 될까?
let serialQueue1 = DispatchQueue(label: "1")
let serialQueue2 = DispatchQueue(label: "2")
let serialQueue3 = DispatchQueue(label: "3")
override func viewDidLoad() {
super.viewDidLoad()
serialQueue1.async {
self.shortWork(1)
}
serialQueue2.async {
self.shortWork(2)
}
serialQueue3.async {
self.shortWork(3)
}
}
func shortWork(_ num:Int){
print("shortWork[\(num)]Start")
print("shortWork[\(num)]End")
}
확인해 본 결과 모두 다른 직렬큐를 사용하는 것은 동시큐를 사용한 것과 같이 순서가 보장되지 않는 형태의 결과가 나왔다
이것으로 동시큐는 임의의 직렬큐들을 사용하는 것이 아닐까 하는 추측할 수 있다.
4. 큐의 종류
4.1 메인큐
let mainQueue = DispatchQueue.main
메인쓰레드를 의미하고, 직렬큐이다.
실제 앱에서는 UI관련작업들이 DispatchQueue.main(메인큐)에서 동작해야 한다.
4.2 글로벌 큐
let userInteractiveQueue = DispatchQueue.global(qos: .userInteractive)
let userInitiatedQueue = DispatchQueue.global(qos: .userInitiated)
let defaultQueue = DispatchQueue.global() // 디폴트 글로벌큐
let utilityQueue = DispatchQueue.global(qos: .utility)
let backgroundQueue = DispatchQueue.global(qos: .background)
let unspecifiedQueue = DispatchQueue.global(qos: .unspecified)
6개의 qos를 가지고 있는 전역 직렬큐이다.
4.3 커스텀 큐
let someQueue = DispatchQueue(label: "some")
label에 따라 분류되며 기본적으로 직렬큐이며 동시큐 설정도 가능하다.