GCD에 관하여 - 2
2023. 3. 10. 19:37ㆍIOS
반응형
동기(Sync)
- 동기란 하나의 작업(문맥)이 끝나기를 기다리는 것
- 위와 같이 동기는 원두를 갈기 -> 컵 준비 -> 얼음 넣기의 각각의 작업이 실행 이후 끝난 다음 이후의 작업이 실행 된다.
비동기(Async)
- 비동기란 이전 혹은 현재의 작업(문맥)이 끝나기를 기다리지 않고 바로 실행함
- 비동기로 실행할 경우 먼저 실행 된 코드보다 이후에 실행 된 코드가 더 먼저 끝날 수도 있다.
- 동기와는 다르게 실행 순서는 다르더라도 작업의 끝을 기다리지 않기 때문에 위와 같이 동작할 수 있다.
- 다만, 여기서 원두 갈기 작업이 먼저 들어갔음에도 컵 준비, 얼음 넣기가 먼저 끝날 수도 있다.
- 또한, 컵 준비 이후에 얼음을 넣어야 하는데 얼음 넣기가 먼저 끝날 수도 있기 때문에 순서가 필요할 경우 주의해야한다.
동시, 직렬, 동기, 비동기 정리
- 동시, 직렬 - 쓰레드가 몇개인가에 따라서 다름(쓰레드가 하나면 직렬, 여러개면 동시)
- 동기, 비동기 - 다음 작업이 언제 시작되느냐에 따라 다름(이전 작업이 끝나기를 기다리면 동기, 기다리지 않는 경우 비동기)
DispatchQueue
디스패치 큐란 작업에 대한 실행을 앱의 메인 쓰레드 혹은 백그라운드 쓰레드에서 직렬로 할지, 동시성으로 할지를 관리해주는 객체이다.
해당 큐는 큐의 자료구조와 같이 FIFO 가장 먼저 들어온 작업이 가장 먼저 나가는 형태로 구현되어 있다.
또한 쓰레드의 경우 시스템에서 관리해주는데 시스템에서는 메인쓰레드를 제외한 쓰레드가 최소 몇개를 할당한다는 것을 보장하지 않는다.
즉 기기에 따라서 현재 자원의 상태에 따라서 시스템에서 적절하게 배분해준다.
우리는 DispatchQueue를 사용할 경우 아래와 같은 두가지 항목을 필수로 생각해야한다.
- Concurrent(동시)인지, Serial(직렬)로 구현을 할 지 첫번째로 정해야한다.
- asyc(비동기), sync(동기) 이 중 어느것으로 작업을 구현 해야할지 정해야한다.
Concurrency Queue, Global Queue
- global Queue는 메소드로 구현되어 있으며, 메소드 실행 시 동시성 큐이기 때문에 쓰레드를 추가로 생성한다.
DispatchQueue.global().async {
}
DispatchQueue.global().sync {
}
DispatchQueue(label: "labelText", attributes: .concurrent).async {
}
DispatchQueue(label: "labelText", attributes: .concurrent).sync {
}
- DispatchQueue를 직접 생성 시
attributes
를 주지 않으면 직렬성 프로그래밍으로 동작하므로 해당 인자에concurrent
를 주어 동시성 속성을 띄는 큐로 만들어야한다.
Serial Queue, Main Thread
- Main 쓰레드의 경우 앱을 실행할 경우 코드 및 UI를 담당하는 쓰레드로 직렬 속성을 가지고 있다.
DispatchQueue.main.async {
}
//DispatchQueue.main.sync { // Error
//}
DispatchQueue(label: "labelText").async {
}
DispatchQueue(label: "labelText").sync {
}
- 위와 같이 메인쓰레드 접근 및 직렬 큐에 동기 비동기 코드블록 클로저를 넣어 실행 할 수 있다.
- DispatchQueue는 기본적으로 생성시 default값이 직렬성 큐 이므로 따로 attributes를 설정해줄 필요가 없다. - init(label:qos:attributes:autoreleaseFrequency:target:) | Apple Developer Documentation
DispatchWorkItem
- 기존 sync, async에 넣는 클로저, 코드블럭을 하나의 객체로 만들어 재사용 가능하도록 만들어주는 객체
let item = DispatchWorkItem {
print("시작!!")
sleep(3)
print("끝")
}
asyncAfter
- 특정 작업을 지정한 시간 이후에 비동기로 처리해준다.
func asyncAfter(
deadline: DispatchTime,
execute: DispatchWorkItem
)
- deadline에서 해당 원하는 시간을 넣어주면 된다.
- 다만, 특정 시간을 넣어줄 경우
async
를 단순히 사용하는것 보다 덜 효율적이다. DispatchTime
의 경우.now
와.distantFuture
이 있는데distantFuture
을 사용하여 값을 특정해주는 것은 하지 말아야한다.
func asyncAfter(
wallDeadline: DispatchWallTime,
execute: DispatchWorkItem
)
wallDeadline
과deadline
을 사용하는 두 버전이 있다.- 두 개의 차이는 시스템 즉 기기의 시간을 기준으로 하느냐 아니냐의 차이이다.
DispatchTime
A point in time relative to the default clock, with nanosecond precision
On Apple platforms, the default clock is based on the Mach absolute time unit.
- 기본 시간 즉, 애플 기기의 시간에 따라 실행됨을 뜻한다.
DispatchWallTime
An absolute point in time according to the wall clock, with microsecond precision.
- Wall Clock에 따른 시간을 의미하는데 Wall Clock은 CPU에서 코드를 실행하는데 있어서 사람이 볼 수 있도록 측정한 시간을 의미한다.
- 즉,
DispatchTime
과는 다르게 코드 자체에의 실행시간을 의미한다.
DispatchQueue.global().asyncAfter(deadline: .now() + 5) {
}
DispatchQueue.global().asyncAfter(wallDeadline: .now() + 5) {
}
- 만약 위와 같이 5초뒤에 실행하는 코드를 작성한다면
deadline
을 사용할 경우 현재 기기의 시간 예를들어 7:30:00이라면 7:30:05일 때 실행될것이고 wallDeadline
은 현재 코드가 실행되는 시간을 독립적으로 측정하여 해당 시간 5초 뒤에 실행을 시켜줄것이다.
asyncAndWait
- 비동기 작업이 끝나기를 기다림으로 어떻게 보면 동기처럼? 작동을 할 수 있게 만들어주는 메소드이다.
반응형
'IOS' 카테고리의 다른 글
[Realm Swift] - “Object type ‘RealmSwiftObject’ is not managed by the Realm. If using a custom `objectClasses` / `objectTypes` array in your configuration, add `RealmSwiftObject` to the list of `objectClasses` / `objectTypes`.” 오류 해결 (1) | 2023.05.31 |
---|---|
GCD에 관하여 - 3 (0) | 2023.03.12 |
GCD에 관하여 - 1 (0) | 2023.03.08 |
TableView Section 글자가 대문자로 변해요~ (0) | 2023.02.25 |
Json Decoding 어떤 문제로 실패한걸까?? (0) | 2023.02.25 |