UI작업이 Main Thread에서 이뤄져야 하는 이유

2022. 5. 20. 13:33iOS 프레임워크

iOS에서 개발을 진행하다 보면, UI 업데이트와 관련된 모든 작업은 main thread에서 작업을 해야 한다는 걸 많이 마주치게 될 것이다.

항상 이에 관한 정확한 이유를 모르고 넘겼지만 이번 기회에 이것을 한번 자세히 정리해보려 한다.

먼저 가장 많이 나타날 개념인 Thread Safe에 대해서 알아보겠다.

Thread Safe란?

멀티 스레드 프로그래밍에서 일반적으로 어떤 함수나 변수, 혹은 객체가 여러 스레드로부터 “동시에” 접근이 이루어져도 프로그램의 실행에 문제가 없음을 의미한다.

UIKit은 기본적으로 Thread Safe하지 않다. UIKit과 같은 매우 큰 프레임워크에서의 모든 속성들을 Thread Safe 하게 설계하는 것은 엄청 비현실적이기에 Serial Queue에서 처리함으로써 Thread Safe 않음으로 생기는 문제들을 해결할 수 있다.

1. UI와 관련된 모든 이벤트 처리를 메인 스레드에서 처리하기 때문이다.

iOS 앱은 여러 Thread를 가지고 있다. 앱을 실행하게 된다면 Cocoa Touch에서 UIApplication 인스턴스가 메인 스레드에서 생성된다.

UIApplication은 앱을 시작할 때 처음으로 인스턴스 화가 되는 부분이며 앱의 전체 Run loop를 포함한 main event loop를 설정하고 event 처리를 시작한다.

앱의 UI Event(사용자의 터치)는 일반적으로 UIApplication → UIWindow → UIViewController → UIView(UIViewController’s View) → subviews (UIButtons 등과 같은 컴포넌트)와 같이 chain으로 연결되는데, 이 responder chain을 따라 UIResponder로 전달된다.

이러한 event chain이 main thread에서 동작하므로 responder chain에 포함된 모든 UI 관련 동작들은 메인 스레드에서 수행되어야 한다.

2. 성능상의 문제가 생길 가능성이 높다.

iOS가 사용자의 화면에 표시하는 렌더링 프로세스는 다음과 같다.

참고 : Core Animation Pipeline

 

Core Animation Pipeline

Commit Transaction Layout 단계: 레이어 정렬 및 위치와 색상을 정의 (layoutSubviews를 호출) Display: draw메서드들이 접근하는 단계. 개발자들은 직접 호출을 못하며 setNeedsDisplay를 사용하여 접근해야한..

ios-dev-skyline-23.tistory.com

이처럼 여러 Thread에서 동시에 UI 업데이트 요청을 보내게 된다면 GPU에 병목현상이 생길 것이고, 많은 시스템 리소스를 사용하는 렌더링 작업을 GPU가 처리할 수 없어 문제가 발생할 가능성이 높다.

3. Main Thread의 View 업데이트 주기가 View Drawing Cycle을 통해 업데이트되기 때문이다.

뷰의 변경사항은 UIApplication에서 생성된 Run Loop의 끝에서 다시 렌더링 된다.

이러면 한 번에 모든 뷰의 변경사항이 처리될 수 있는데, 이를 View Drawing Cycle이라고 한다.

만약 Background Thread에서 각각의 Run-Loop대로 업데이트가 될 경우 각자의 갱신주기를 따로 가지며 View들이 제멋대로 동작할 확률이 높다.

'iOS 프레임워크' 카테고리의 다른 글

SwiftUI - 조심스러운 첫 걸음  (0) 2023.11.30
NSLock  (0) 2022.05.25
Core Animation Pipeline  (0) 2022.05.24
CADisplayLink  (2) 2022.05.23
CGRect, CGSize, CGPoint에 대하여  (0) 2022.04.28