1) 반드시 메인큐에서 처리해야하는 작업
★ 중요하게 알아야할 한가지 개념 ★
- UI 관련일들은 “메인큐”에서 처리해야 한다. → 화면을 그리는 일
- UI 업데이트가 어떻게 이뤄지는지 아래 개략도를 보면 된다.
- 모든 OS에서 화면을 업데이트하거나 표시하는 UI 작업을 하나의 쓰레드에서만 작업해야하는 특징이 있어서 메인 스레드에서 처리해야한다. → 애플에서 왜 이렇게 만들었는지 확인할 필요가 있음
2) sync 메서드에 대한 주의사항
- sync 메서드와 관련해 절대 해서는 안되는 코드 2가지가 있다.
1. 메인큐에서는 다른큐로 작업을 보낼때 sync 메서드를 부르면 절대 안된다.
- 메인큐에서는 항상 비동기적으로 보내야한다.
- 즉, UI와 관련되지 않은 오래 걸리는 작업(네트워크)들은 다른 쓰레드에서 일을 할 수 있도록 “비동기적(async)”으로 실행하여야 하며, 동기적으로 시키면 UI가 멈춰서 유저한테 반응을 늦게 하고 버벅거린다.
2. 현재의 큐에서 현재의 큐로 “동기적으로” 보내서는 안된다.
- 현재의 큐를 블락하는 동시에 다시 현재의 큐에 접근하기 때문에 교착상황(DeadLock)이 발생한다.
3) weak, strong 캡처 주의
4) 컴플리션 핸들러의 존재 이유
- 비동기로 작업을 시키고 나서, 작업에 해당하는 값을 바로 사용하면 안된다.
- 작업이 아직 종료하지 않았는데, 해당 값에 접근하면, 잘못된 값을 사용할 확률이 높다.
- 그래서, 해당 비동기 작업이 끝났다는 것을 정확히 알려주는 시점이 컴플리션 핸들러 이다.
- 비동기 함수와 관련된 작업들은 모두 컴플리션 핸들러를 가지고 있다.
5) 동기적 함수를 비동기 함수처럼 만드는 방법
- 동기적 함수를 비동기 함수처럼 만드는 이유는 여러번 재활용을 하기 위해서이다.
6) 기타
- URLSession과 같은 이미 비동기 함수는 GCD/Operation이 필요없다. → 이미 내장되어 있음
7) weak self와 관련된 상세 내용
DispatchQueue.global().async { [weak self] in
DispatchQueue.main.async {
}
}
- 위의 경우에는 맨위 클로저에 weak self 를 선언해주면 밑에 클로저에도 적용이 된다.
- 이를 이해하기 위해서는 ARC와 클로저의 캡처 리스트에 대한 내용을 이해해야한다.
- 코드를 작성할 경우 각 코드들이 메모리에 어떻게 올라가는지 알고 있어야 한다.
- 클래스, 클로저 → 힙영역 저장
- 구조체, enum, 자료형 (구조체로 만들어짐), 함수 → 스택 영역
- 강한참조, 약한참조
- 위 내용을 이해하기 위해서 아래와 같은 예제를 들었다.
class viewController: UIViewController {
var name: String = "뷰컨"
func doSomething() {
DispatchQueue.global().async {
sleep(3)
print("글로벌큐에서 출력하기: \(self.name)")
DispatchQueue.main.async {
print("메인큐에서 출력하기: \(self.name)")
}
}
}
deinit {
print("\(name) 메모리 해제")
}
}
func localScopeFunction() {
let vc = ViewController()
vc.doSomething()
}
localScopeFunction()
- 위 코드가 메모리에서 작동하는 과정은 아래와 같다.
- localScopeFunction() 작동 → vc 객체 생성 → ViewController ARC == 1 (+1)
- vc 내부 doSomething() 작동
- doSomething() 내부 클로저가 self 메타타입을 통해서 ViewController 객체를 가리키면서 ViewController ARC == 2 (+1)가 된다.
- doSomething() 함수가 종료되면서 localScopeFunction() 함수도 종료되면서 vc 객체가 사라지면서 ViewController의 ARC == 1 (-1)이 된다.
- 그러나 여기서 문제점이 클로저 내부의 작업들이 다른 스레드에서 동작하고 있게 되면서 vc 객체가 사라졌는데도 ViewController의 ARC == 1로 남아있게 된다.
- 위와 같은 문제점을 해결하기 위해 weak self 를 선언해줘서 self를 약한 참조하도록 만들어준다.
'IT > iOS' 카테고리의 다른 글
iOS Concurrency 프로그래밍, 동기/비동기 처리, GCD/Operation 에 대한 이해 (5) (0) | 2023.05.30 |
---|---|
iOS Concurrency 프로그래밍, 동기/비동기 처리, GCD/Operation 에 대한 이해 (4) (0) | 2023.05.30 |
iOS Concurrency 프로그래밍, 동기/비동기 처리, GCD/Operation 에 대한 이해 (2) (0) | 2023.05.30 |
iOS Concurrency 프로그래밍, 동기/비동기 처리, GCD/Operation 에 대한 이해 (1) (0) | 2023.05.30 |
iOS Concurrency 프로그래밍, 동기/비동기 처리, GCD/Operation 에 대한 이해 (0) (0) | 2023.05.30 |