본문 바로가기

iOS

[iOS] RunLoop

RunLoop

안녕하세요 :)

 

오늘은 RunLoop에 대해서 알아보도록 할게요!

 

모든 포스트는 편의 말투로 작성합니다 :D

 

RunLoop란


image

A run loop is an event processing loop that you use to schedule work and coordinate the receipt of incoming events. The purpose of a run loop is to keep your thread busy when there is work to do and put your thread to sleep when there is none.

 

Apple은 RunLoop를 위와 같이 설명하고 있어요.

  • 작업을 스케줄링하고 들어오는 이벤트들을 조정하기 위해 사용되는 이벤트 처리 루프.
  • 마우스 혹은 키보드와 같은 윈도우 시스템과 포트 객체로부터의 입력 이벤트 뿐 만 아니라 타이머와 관련된 이벤트를 처리하는 루프에요.
  • 스레드가 일을 해야 할 때는 일을 하도록 하고, 일이 없으면 쉬도록 스레드의 업무를 관리하기 위한 목적으로 고안되었다고 해요.
  • RunLoop 클래스는 일반적으로 Thread-Safe 하지 않기 때문에 해당 컨텍스트에 맞는 스레드에서만 호출하는 것을 권장하고 있어요.
  • Main RunLoop를 제외한 나머지 RunLoop를 Manually 하게 관리해요.

다른 프로그래밍 언어에서는 주로 event loop 라는 용어로 사용되는 개념이에요.

 

뭐.. RunLoop가 무엇인지는 아주 살~~짝 알겠는데 이게 내부에서 어떻게 동작하는거지..?

 

자 같이 동작 원리를 살펴봅시당

 

RunLoop 동작 원리


RunLoop는 도착한 이벤트에 대한 이벤트 핸들러를 수행하는 루프에요.

 

이름이 Loop이긴 하지만 하지만 내부적으로 계속해서 반복을 수행하는건 아니라 스레드의 작업 루틴 안에서 명시적으로 반복을 수행하고, 이 안에서 RunLoop를 수행해야해요

 

RunLoop는 2가지의 이벤트 소스를 받아요.


이 2가지 소스로부터 발생한 이벤트를 정의해놓은 이벤트 핸들러를 통해 처리하게 되요.

 

image

 

1. Input Source: 다른 스레드나 애플리케이션으로 부터 온 이벤트를 비동기적으로 처리해요.

 

2. Timer Source: 예정된 시간 혹은 일정 주기로 반복되는 이벤트를 동기적으로 처리해요.

 

위 그림 중 왼쪽 그림의 노란색 루프를 한 바퀴 도는 작업이 한번의 실행이라고 했을때, 실행동안 스레드에 도착한 이벤트를 받고, 이에 대한 핸들러를 수행해요.

 

위에서 얘기했듯 RunLoop가 자체적으로 계속 이벤트가 들어오나 안들어오나 알아서 반복적으로 확인하는 것은 아니고 한번 이벤트 소스를 읽고 전달하는 실행이 끝나면 그대로 대기하게 되요 :D

 

Main RunLoop


위에서 모든 RunLoop는 개발자의 별도 생성 및 실행이 필요하다고 했어요!

 

하지만 요놈은 제외입니다.

 

Main RunLoop는 별개로 애플리케이션이 실행될 때 프레임워크 차원에서 자동으로 설정하고 실행해요.

 

image

유저가 앱 아이콘을 터치하고 나서의 흐름이에요.

main() 함수를 호출하고 일련의 과정을 거쳐 초기 셋팅이 완료되어 Active 상태에 들어가게 되면 RunLoop가 본인의 몫을 시작해요.

image

유저의 터치 이벤트가 들어오면 내부 이벤트 큐에 쌓여있다가 위에서 얘기했던 이벤트 소스를 통해 Main RunLoop에 의해 처리되요.

이 부분에 대해서는 좀 더 자세히 나중에 정리해보도록 할게요!

 

그럼 RunLoop는 언제 사용해야 할까?


RunLoop는 스레드와의 더 많은 상호작용을 위한 거에요, 예를 들어 아래와 같은 작업을 수행하고자 할 때 RunLoop를 이용해요.

  1. port 또는 custom input source를 활용하여 다른 스레드와 통신해야 하는 경우
  2. thread에서 Timer 를 사용해야 하는 경우
  3. Cocoa application의 performSelector 메서드를 사용해야 하는 경우
  4. 주기적인 작업을 수행하기 위해 스레드를 유지해야 하는 경우

이러한 경우를 제외하고는 RunLoop를 사용할 일은 거의 없다고 하네요ㅠㅠ

실제 사용 예시나 Best Practice 를 찾아보면 분명 생각치도 못한 곳에 많이 응용해서 사용이 될 것 같아요!

 

Reference