seong_hye, the developer

Swift) DispatchSourceTimer이란? 본문

IOS

Swift) DispatchSourceTimer이란?

seong_hye 2022. 8. 2.

 

📘 Swift) DispatchSoureTimer

알람 앱을 사용하다보면 백그라운드에 있어도 타이머가 잘 진행되는 모습을 볼 수 있다

이번에는 그렇게 백그라운드에서 실행될 수 있는 타이머에 대해 알아보자


🔹 문법 설명

GCD(Grand Central Dispatch) 기반으로 정밀하고 효율적인 타이머를 만들 수 있게 해주는 객체

Timer보다 더 낮은 수준에서 제어 가능

백그라운드에서 안정적으로 동작

반복주기, 시작 시점, 허용 오차 등을 세밀하게 조절 가능


🔹 주요 구성 요소

구성 설명
DispatchSource.makeTimerSource(queue:) 타이머 생성, 큐는 실행할 대상 지정
schedule(deadline:repeating:leeway:) 시작 시점, 반복 주기, 허용 오차
setEventHandler 주기마다 실행할 코드 지정
resume() 타이머 시작
cancel() 타이머 종료 (메모리 해제까지 필수)

📌 주의사항

- resume()cancel()은 한 번만 호출해야 함 ~> 중복 호출 시 크래시 발생

- 타이머를 재시작하고 싶으면 cancel() 후 새로 생성해야 함

- DispatchSourceTimer강한 참조를 가지므로 클래스나 구조체 내에서

weak 또는 명시적 해제 처리를 고려해야 함


🔹사용 예시

class ExampleTimer() {
	private var timer: DispatchSoureTimer?
    
    func startTimer() {
    	// 백그라운드 큐 또는 메인 큐 설정
    	let queue = DispatchQueue.global()
        
        //타이머 생성
        timer = DispatchSource.makeTimerSource(queue: queue)
        
        //시작 시간, 간격, 허용 오차 설정
        timer?.schedule(deadline: .now(), repeating: 1.0, leeway: .milliseconds(100))
        
        //이벤트 핸들러 설정
        timer?.setEventHandler {
        	print("타이머 실행됨: \(Date())")
        }
        
        //타이머 시작
        timer?.resume()
    }
    
    func stopTimer() {
    	timer?.cancel()
        timer = nil
    }
}

🔹Timer와의 차이점

Timer ( Foundation.Timer)

주로 SwiftUI와 UIKit에서 간단한 용도로 많이 사용

let timer = Timer.scheduledTImer(withTimeInterval: 1.0, repeats: true) { _ in
	// 실행 시 내용
}

📌 특징

- 메인 런루프 또는 RunLoop에 등록됨

- 간편하게 사용 가능 (scheduledTimer)

- SwiftUI에서는 .timer Publisher로 Combine과 연동 가능

- 정확도는 낮음 (특히 백그라운드나 부하 많을 때 지연 가능)

- 앱이 백그라운드로 전화되면 멈추거나 제한될 수 있음

 

DispatchSourceTimer (GCD)

성능이 중요한 상황, 정밀도나 백그라운드 동작이 중요한 경우 사용

let timer = DispatchSource.makeTimerSource(queue: .global())
timer?.schedule(deadline: .now(), repeating: 1.0)
timer?.setEventHandler { print("타이머 실행됨: \(Date())")}
timer?.resume()

📌 특징

- GCD 기반으로 백그라운드에서도 정확하게 실행

- 오차 (leeway) 설정 가능

- 더 정밀하고 낮은 오버헤드

- 직접 cancel() 및 resume() 관리 필요

 - UI 업데이트 시 DispatchQueue.main.async 필요

- suspend()된 상태로 시작되므로 반드시 resume() 필요


🔍 주요 차이점 비교

항목 Timer DispatchSourceTimer
생성 편의성 매우 쉬움 코드 좀 더 복잡
정확도 낮음(지연 발생 가능) 높음
백그라운드 동작 앱 상태에 따라 중단 가능 백그라운드에서도 동작 안정적
커스터마이징(leeway, 우선순위) 거의 없음 가능
메모리 관리 자동 해제 가능 수동으로 cancel() 필요
실행 위치 RunLoop 필요 (기본: main) GCD 큐 (main/global 선택 가능)
사용 환경 일반 UI 작업, SwiftUI Combine 실시간 처리, 정밀 제어, 백그라운드 작업

 

Comments