Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- uitableview
- 리펙터링
- Protocol
- Human interface guide
- Xcode
- collectionview
- 스위프트
- Observable
- combine
- uiscrollview
- 클린 코드
- 애니메이션
- Clean Code
- 리팩토링
- Refactoring
- map
- swift documentation
- swiftUI
- SWIFT
- HIG
- tableView
- rxswift
- MVVM
- UITextView
- 리펙토링
- UICollectionView
- clean architecture
- ios
- ribs
- RxCocoa
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] DispatchQueue.main.sync와 DispatchQueue.main.async 이해하기, sync를 사용해야하는 상황 (#mainSyncSafe) 본문
iOS 응용 (swift)
[iOS - swift] DispatchQueue.main.sync와 DispatchQueue.main.async 이해하기, sync를 사용해야하는 상황 (#mainSyncSafe)
jake-kim 2023. 7. 24. 01:51DispatchQueue의 sync와 async 동작
- main queue와 thread 구분하기
- main thread는 single thread이며, 해당 작업을 처리하는곳이 queue
- async와 sync로 각각 queue에 작업 담기가 가능
DispatchQueue.main.async { // main queue에 async 작업 넣는 곳 }
DispatchQueue.main.sync { // main queue에 sync 작업 넣는 곳 }
- ViewController를 생성하고 DispatchQueue.main 없이 코드를 작성하면 그 코드들은 모두 DispatchQueue.main.sync 큐에서 처리
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// run at main thread synchronously
print(123)
}
}
- 만약 DispatchQueue.global().async 로 다른 함수를 호출했을때는 호출된 함수 내부에서는 background thread로 동작
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// run at main thread synchronously
print(123)
}
func runOnBackgroundThread() {
DispatchQueue.global().async {
self.someCode()
}
print("out of background thread?", Thread.isMainThread) // true
}
func someCode() {
print("Thread.isMainThread?", Thread.isMainThread) // false
}
}
mainSyncSafe 개념
- 앞에서 알아보았듯이 일반적으로 코드를 입력하면 main에서 sync하게 동작
- deadlock 현상
- sync로 작업을 추가하면 큐에서는 이 일을 우선순위로 보고 처리하려고 하고, 동시에 sync하게 들어갔으므로 print(123)작업은 이전에 들어간 task들이 끝나기를 기다리며 무한정 기다리는 문제가 발생
- mainSyncSafe 라는것을 DispatchQueue 확장으로 만들어서 현재 스레드가 메인 스레드이면 바로 실행하고, 메인 스레드가 아니면 sync하게 동작하도록 구현
extension DispatchQueue {
static func mainSyncSafe(execute work: () -> Void) {
if Thread.isMainThread {
work()
} else {
DispatchQueue.main.sync(execute: work)
}
}
}
sync, async 코드로 이해하기
- only sync
- 코드 순서상 위에서 아래로 실행
func syncOnlySample() {
print("start only sync \n")
DispatchQueue.mainSyncSafe {
print(1)
print(11)
}
print("\nbetween 1 and 2\n")
DispatchQueue.mainSyncSafe {
print(2)
print(22)
}
print("\nbetween 2 and 3\n")
DispatchQueue.mainSyncSafe {
print(3)
print(33)
}
print("\nbetween 3 and 4\n")
DispatchQueue.mainSyncSafe {
print(4)
print(44)
}
}
/*
start only sync
1
11
between 1 and 2
2
22
between 2 and 3
3
33
between 3 and 4
4
44
*/
- only async
- async 블록으로 감싸지 않으면 우선순위는 sync가 높으므로 sync 작업들이 다 처리된 후 async 작업들이 호출
- async는 이전에 큐에 담긴 작업들이 끝나는 것을 기다리지 않으므로 메인 큐에 print("nbetween 1 and 2\n")보다 print(1)가 먼저 담겼지만 print(1)가 나중에 실행
func asyncOnlySample() {
print("start only async \n")
DispatchQueue.main.async {
print(1)
print(11)
}
print("\nbetween 1 and 2\n")
DispatchQueue.main.async {
print(2)
print(22)
}
print("\nbetween 2 and 3\n")
DispatchQueue.main.async {
print(3)
print(33)
}
print("\nbetween 3 and 4\n")
DispatchQueue.main.async {
print(4)
print(44)
}
}
/*
start only async
between 1 and 2
between 2 and 3
between 3 and 4
1
11
2
22
3
33
4
44
*/
- async보다 sync의 우선순위가 높은 것을 확인해볼수 있는 예제
- 메인 큐에 추가된 것은 print(1)가 print(2)보다 더욱 빠르게 추가됐지만, print(2)가 먼저 실행
func combinationSample1() {
print("start multi Thread \n")
DispatchQueue.main.async {
print(1)
print(11)
}
print("\nbetween 1 and 2\n")
DispatchQueue.mainSyncSafe {
print(2)
print(22)
}
}
/*
start multi Thread
between 1 and 2
2
22
1
11
*/
sync를 언제 사용해야할까?
- 대부분 async를 사용하여 main thread를 관리하면 deadlock을 예방할 수 있지만 sync를 특별한 경우에 사용해야하는 케이스가 존재
- sync를 사용해야하는 경우?
- UI 업데이트가 순서대로 처리되어야 하는 경우
- 여러개의 UI 업데이트에 있어서, 우선순위가 높은 업데이트를 해주고 싶은 경우, sync를 사용하여 메인 스레드를 점유할 수 있도록 구현
* 전체 코드: https://github.com/JK0369/ExMainThread
* 참고
https://gist.github.com/sgr-ksmt/4880c5df5aeec9e558622cd6d5b477cb
'iOS 응용 (swift)' 카테고리의 다른 글
Comments