[iOS 12주차] iOS: RunLoop

DoyleHWorks·3일 전
0

RunLoop

iOS의 RunLoop란 무엇인가?

RunLoop는 iOS와 macOS에서 애플리케이션이 이벤트를 처리하고 유휴 상태를 관리하는 중심적인 메커니즘이다. 이는 이벤트 기반 프로그래밍의 핵심으로, 프로그램이 계속 실행되는 동안 특정 작업(입력 이벤트, 타이머, 네트워크 이벤트 등)을 처리할 수 있도록 한다.


RunLoop의 주요 역할

  1. 이벤트 처리: 터치 이벤트, 네트워크 응답, 타이머, 시스템 알림 등을 처리한다.
  2. 유휴 상태 관리: 작업이 없을 때 유휴 상태로 전환하여 CPU 사용량을 줄이고, 이벤트가 발생하면 즉시 처리한다.
  3. 쓰레드 관리: 메인 쓰레드와 백그라운드 쓰레드에서 실행되며, 각 쓰레드는 자체 RunLoop를 가진다.

RunLoop 구조

RunLoop는 크게 두 가지 구성 요소로 나눌 수 있다:
1. Input Sources (입력 소스)

  • Port-based Sources: 시스템 이벤트 처리. (e.g., NSPort, 네트워크 소켓 등)
  • Custom Input Sources: 사용자 정의 이벤트 처리. (e.g., 앱에서 직접 추가한 이벤트)
  1. Timer Sources (타이머 소스)
    • 일정 시간 간격으로 작업을 실행할 수 있도록 타이머를 추가한다.

RunLoop의 동작 원리

  1. RunLoop 실행 시작:
    RunLoop는 대기 상태로 들어가 이벤트 소스나 타이머가 발생하기를 기다린다.

  2. 이벤트 발생 확인:
    입력 소스나 타이머에서 이벤트가 발생하면 이를 확인한다.

  3. 핸들러 호출:
    적절한 이벤트 핸들러를 호출하여 작업을 수행한다.

  4. 유휴 상태 전환:
    다음 이벤트가 발생할 때까지 대기 상태로 전환한다.


RunLoop 관리

  • 메인 쓰레드의 RunLoop
    메인 쓰레드는 기본적으로 RunLoop가 자동으로 관리된다. 이 RunLoop는 UIKit의 이벤트를 처리하고 애플리케이션의 UI를 업데이트하는 데 사용된다.

  • 백그라운드 쓰레드의 RunLoop
    백그라운드 쓰레드에서는 기본적으로 RunLoop가 실행되지 않으므로, 직접 RunLoop를 생성하고 실행해야 한다.


RunLoop 사용 코드 예제

Timer 추가 예제

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 5초마다 실행되는 Timer 추가
        Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
    }
    
    @objc func timerFired() {
        print("Timer fired!")
    }
}

백그라운드 쓰레드에서 RunLoop 실행

DispatchQueue.global().async {
    // 현재 쓰레드에 RunLoop를 실행
    let runLoop = RunLoop.current
    
    // 10초마다 실행되는 Timer 추가
    Timer.scheduledTimer(withTimeInterval: 10.0, repeats: true) { timer in
        print("Background timer fired!")
    }
    
    // RunLoop 실행
    runLoop.run()
}

RunLoop와 관련된 클래스

  1. CFRunLoop: Core Foundation 레벨의 RunLoop API로, 더 낮은 수준의 제어를 제공한다.
  2. NSRunLoop: Foundation에서 제공하는 Objective-C 인터페이스. Swift에서도 사용 가능.

RunLoop의 모드 (RunLoop Modes)

RunLoop는 모드라는 개념을 사용하여 특정 이벤트 소스만 활성화한다.
대표적인 모드는 다음과 같다:

  • default (기본 모드)
    대부분의 일반 작업은 이 모드에서 처리됨.

  • UITrackingRunLoopMode (UI 추적 모드)
    스크롤 같은 UI 트래킹 이벤트를 처리할 때 사용됨.

  • commonModes
    여러 모드에서 공통적으로 이벤트를 처리할 수 있도록 설정된 모드.


RunLoop와 AutoReleasePool

RunLoop의 각 루프 사이클은 자동으로 AutoReleasePool을 생성하고 소멸시킨다. 이는 메모리 관리를 최적화하여 반복되는 이벤트 처리에서도 메모리 누수를 방지한다.


추가적으로 알아두면 좋은 점

  • RunLoop를 강제로 중지하려면 CFRunLoopStop이나 CFRunLoopWakeUp을 사용.
  • UI 업데이트는 항상 메인 쓰레드에서 실행해야 함.
  • 네트워크 작업이나 비동기 작업은 RunLoop와 긴밀히 연결될 수 있음.
profile
Reciprocity lies in knowing enough

0개의 댓글