일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- array
- struct
- NotificationCenter
- Observer
- list
- SWIFTUI
- self
- calendar
- escaping
- http
- viewlifecycle
- ScrollView
- 고차함수
- SWIFT
- Animation
- Switch
- class
- 글또
- mvvm
- Git
- apns
- 화면전환
- segue
- protocol
- PushNotification
- error
- uikit
- singleton
- Refresh
- IOS
- Today
- Total
seong_hye, the developer
Swift) DispatchSourceTimer이란? 본문
📘 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 | 실시간 처리, 정밀 제어, 백그라운드 작업 |
'IOS' 카테고리의 다른 글
Swift) 문법 정리 - COW(Copy-On-Write) (0) | 2022.08.02 |
---|---|
Swift) 백그라운드 실행(Background Execution) (0) | 2022.08.02 |
Swift) NotificationCenter이란? (0) | 2022.07.26 |
Swift) Class vs Struct (0) | 2022.07.26 |
Swift) 문법 정리 - 싱글톤(Singleton) 패턴 (0) | 2022.07.26 |