티스토리 뷰
안녕하세요 :) Zedd입니다.
DispatchQueue를 더 깊이 알아봅시다. 안깊을수도 있음 ㅎ_ㅎ..
DispatchQueue의 QoS와 workItem의 QoS, 그리고 Dispatch Group에 대해 알아볼게요.
개념말고;; 사용법ㅎㅎ
읽기전에 <GCD - Dispatch Queue사용법 (1)> 을 읽고오시는 걸 추천
GCD - Dispatch Queue사용법 (2)
QoS를 또 이 글에서 적는 건 아닌 것 같아서 따로 정리 ㄱ
<Prioritize Work with Quality of Service Classes>
문서 중간중간 이해가 안가는 부분들이 몇개 있었지만..가장 중요한건 QoS가 뭐가 있냐!!!! 그게 제일 중요한 것 같아요. 그리고 각각의 QoS가 어떤 곳?..어떨 때 쓰여야 하는지 뭐 예를들어 사용자와 계속 상호작용을 해야하는지, 아니면 안해도 되는지 뭐 그런것들? 그런것들만 알면 QoS에 대해....뭐 다 아는거라고 할 수 있을 것 같....!!
그럼 DispatchQueue의 QoS를 알아봅시다.
일단 Queue자체에 QoS를 달리 주면 어떻게 될까요
let zeddQueue = DispatchQueue(label: "zedd" ,qos: .userInitiated)
let alanQueue = DispatchQueue(label: "alanWalker", qos: .utility)
zeddQueue.async {
for i in 1...5 {
print("👻 \(i)")
}
}
alanQueue.async {
for i in 100...105{
print("🌕 \(i)")
}
}
zeddQueue👻에 더 중요한? 더 높은 QoS를 주었습니다! 어떻게 될까요?
ZeddQueue👻가 대부분의 경우 먼저 실행되고 있어요.
지금 두 Queue가 Serial이긴 하지만, task가 하나씩 있기 때문에 의미없고, async로 돌렸음에도 불구하고 ZeddQueue👻가 먼저 실행되는 것이죠.
alanQueue도 ZeddQueue와 똑같이 userInitiated를 주게되면, 매번...실행결과가 달라지긴 하지만,(물론 위 결과도 매번 달라지긴 하지만)
조금 균형있게? 나오게 됩니다.
오옹
ㅇㅋㅇㅋ
그럼 이제 workItem을 보면 되는 부분
일단 workItem에 QoS를 줄건데, 그럼 이제 queue하나만 필요하겠죠? 그 하나의 Queue안에서 뭐 QoS에 따른
실행순서를 결정할 것이니까요.
let myQueue = DispatchQueue(label: "myQueue")
let zeddItem = DispatchWorkItem(qos: .userInitiated) {
for i in 1...5 {
print("👻 \(i)")
}
}
let alanItem = DispatchWorkItem(qos: .userInitiated) {
for i in 100...105 {
print("🌕 \(i)")
}
}
myQueue.async(execute: zeddItem)
myQueue.async(execute: alanItem)
흐음 이게 코드가 길어지니까 가독성이 조금 떨어지네요..
아무튼 이렇게 하면..어떻게 될 것 같으신가요 ㅎ
네..그렇습니다..무슨 workItem을 “먼저” 넣었냐에 따라 다르겠죠? 왜냐!!! 지금 하나의 queue에서 작업중인데, queue만들 때 attributes로 concurrent안줬죠ㅎ;; 여기서 QoS를 뭘 어떻게 다르게 줘도 먼저 넣은게 먼저 서비스를 받고 Serial이기 때문에..........먼저 넣은게 끝나야 다음 task가 실행을 하게 되니까 ㅎㅎ;
오 gist깐지..암튼..이렇게 queue를 concurrent로 바꿔줍시다.
그리고 지금 QoS가 다른거 보이죠?!?! Zedd. 즉 유령👻이 더 QoS가 높으니 유령이 먼저 실행되면 좋겠는데요
앗 왼쪽꺼 캡쳐에 머지..암튼 대체로 이런 양상을 띈..? 유령이 먼저 실행되게 됩니다.
concurrent임에도 불구하고!!!!
둘다 qos를 똑같이 주면
당연히 뭐 이런 패턴? 둘다 골고루 나오는 그런 걸 텐데.. QoS를 다르게 주니 Operation에서의 addDependency준 것 처럼....뭔가 할 수 있을 것 같네요.
operation은 각 개별 작업에 대해 priority를 줄 수 있고, GCD에서는 queue에 대한 priority만 줄 수 있다고 봤었는데..역시 직접 써봐야 하는군요.
아닌가..? GCD에서도 Queue에 대한 우선순위와 작업에 대한 우선순위 둘 다 줄 수 있는...거 아닌가요?!?!?!?
흠
아!! 또 <Prioritize Work with Quality of Service Classes> 글에서 배운 QoS promotion rule도 잠깐 볼 수 있겠죠. 우리는 queue에 QoS를 안줬으니까
요게 적용이 되겠네요...?
아무튼 DispatchGroup으로 ㄱㄱ
한번도 안써봤....
Dispatch Group
일단 문서를 보면,
dispatch Group은 작업의 synchronization을 집계(?)(aggregate)를 허용합니다. 이를 사용하여 서로 다른 queue에서 실행될 수 있지만, 여러개의 다른 작업 item을제출(submit)하고, 모든 작업이 완료되면, 이를 추적(track)할 수 있습니다. 이 동작은 지정된 모든 작업이 완료될 때 까지 기다려야 하는 경우, 유용 할 수 있습니다.
let myGroup = DispatchGroup()
일단 이렇게 DispatchGroup을 하나 만들고
myQueue.async(group: myGroup) {
for i in 100...105 {
print("🌕 \(i)")
}
}
myQueue.async(group: myGroup) {
for i in 1...5 {
print("👻 \(i)")
}
}
나의 task를 어느 group에서 할지 지정 할 수 있어요.
이렇게 하면..!
myGroup.notify(queue: myQueue) {
print("end!")
}
내 DispatchGroup에 대해서 notify라는 메소드를 호출 할 수 있는데, 파라미터로 큐를 받네요.
아니 왜이렇게 GCD메소드에는 특히 Swift는 왜이렇게 문서에 Discription이 없지?
아무튼 이렇게 하면, 저 Group에 들어간 task들이 모두 끝나면!!! notify가 호출되어 end!가 출력되게 됩니다.
다~~ 실행하고 뭔가를 해주고 싶을 때 유용하겠네요!
후행클로져가 있으니..........굉장히 꿀인 부분
이렇게도 할 수 이씀 ㅎㅎ 물론 notify도 저 notify 클로져 안에 있어야 합니당. 바깥에 있으면 위에 있던 작업에 대해서 불림ㅁ
이러면 이렇게 하면 저의 completionHandler들이 조금 정리될...수...있..을 것 같네요.
아주 잘 만든 것 같음
'iOS' 카테고리의 다른 글
iOS ) UIResponder (5) | 2018.05.26 |
---|---|
iOS ) AVKit과 AVFoundation (1) | 2018.05.13 |
iOS ) Prioritize Work with Quality of Service Classes (0) | 2018.04.29 |
iOS ) GCD - Dispatch Queue사용법 (1) (5) | 2018.04.29 |
iOS ) 왜 main.sync를 하면 안될까 (9) | 2018.04.29 |
- fastlane
- ios 13
- Combine
- SwiftUI
- WWDC
- swift3
- 피아노
- np-hard
- Xcode
- swift delegate
- Git
- Accessibility
- WidgetKit
- UIBezierPath
- swift array
- WKWebView
- swift tutorial
- github
- Swift
- np-complete
- actor
- FLUTTER
- iOS delegate
- swift sort
- 스위프트
- 스위프트 문법
- swift 공부
- 회고
- 제이슨 파싱
- IOS
- Total
- Today
- Yesterday