iOS 앱(APP)에서 시간이 적게 드는 작업(Task)이 1번 쓰레드(Main Thread)에 집중되어 있으면, 업데이트 사이클(Update Cycle)의 실행 간격이 좁기 때문에 큰 불편함 없이 앱을 사용할 수 있습니다.
하지만 시간이 많이 드는 작업이 1번 쓰레드에 집중되어 있으면, 업데이트 사이클의 실행 간격이 넓어지기 때문에 앱 작동에 있어 버벅임이 발생할 수 있습니다.
때문에 원활하고 매끄러운 앱 사용을 추구하기 위해서는 1번 쓰레드에 몰려있는 작업을 다른 쓰레드(2번~n번 쓰레드)로 분산처리 해야 합니다.
이러한 분산 처리 과정을 "동시성 프로그래밍/비동기 처리"라 부릅니다.
✅ 버벅임의 예시 코드
아래의 코드는 sleep() 함수를 사용하여 작동의 버벅임을 표현한 예시 코드입니다.
각각의
work_n()
함수는 2.XX초의 작업시간을 가지고 있으며, 이러한 함수 5개가 1번 쓰레드에서 작동하게 되어 약 10.XX초의 시간을 소비하고 있습니다.func work_1(){ print("작업1 시작") sleep(2) print("종료1\n") } func work_2(){ print("작업2 시작") sleep(2) print("종료2\n") } func work_3(){ print("작업3 시작") sleep(2) print("종료3\n") } func work_4(){ print("작업4 시작") sleep(2) print("종료4\n") } func work_5(){ print("작업5 시작") sleep(2) print("종료5\n") } work_1() work_2() work_3() work_4() work_5() /* 출력 결과 작업1 시작 종료1 작업2 시작 종료2 작업3 시작 종료3 작업4 시작 종료4 작업5 시작 종료5 */
iOS 환경에서 작동하는 앱(APP)의 분산 처리 과정(동시성 프로그래밍/비동기 처리)은 생각보다 간단합니다.
1번 쓰레드(Main Thread)에 몰려있는 작업(Task)을 대기행렬 큐(Queue)로 보내면, 운영체제(iOS)가 자동으로 다른 쓰레드(2번~n번 쓰레드)에게 순차적으로 분산 처리해주기 때문입니다.
큐에 있는 작업을 다른 쓰레드로 보내는 일은 운영체제의 역할입니다. 그 때문에 개발자는 1번 쓰레드에 몰려있는 작업을 대기행렬 큐(Queue)로 보내는 작업만을 하면 됩니다.
대기행렬 큐(Queue)에는 크게 2가지 종류가 있습니다.
1. ⭐️Dispatch Queue(GCD)⭐️ (가장 기본적이며, 많이 사용하는 방법)
2. Operation Queue
✅ 버벅임 해결의 예시 코드 (Dispatch Queue 사용)
1번 쓰레드에 집중된 작업을 다른 쓰레드로 분산처리 하면 버벅임을 해결할 수 있습니다.
집중된 작업을 다른 쓰레드로 분산처리 하는 클로저 코드
DispatchQueue.global().async{ }
DispatchQueue.global().async{ } // 비동기 방식의 분산처리
를 사용하여 총 작업시간을 10.XX초에서 2.XX초로 단축할 수 있습니다.
하지만 각각의 작업을 분산하여 작업할 경우 어떠한 작업이 먼저 시작하고 먼저 끝날지 모르기 때문에 출력 결과가 일정하지 않습니다. (작업의 순서가 중요한 경우 직렬(Serial) 방식으로 처리)
func work_1(){ print("작업1 시작") sleep(2) print("종료1\n") } func work_2(){ print("작업2 시작") sleep(2) print("종료2\n") } func work_3(){ print("작업3 시작") sleep(2) print("종료3\n") } func work_4(){ print("작업4 시작") sleep(2) print("종료4\n") } func work_5(){ print("작업5 시작") sleep(2) print("종료5\n") } DispatchQueue.global().async { work_1() } DispatchQueue.global().async { work_2() } DispatchQueue.global().async { work_3() } DispatchQueue.global().async { work_4() } DispatchQueue.global().async { work_5() } /* 출력 결과 작업1 시작 작업2 시작 작업3 시작 작업5 시작 작업4 시작 종료1 종료4 종료5 종료2 종료3 */