Apple cung cấp class Timer để thực thi tác vụ sau một khoảng thời gian nhất định, gửi message đến target object.
Ví dụ: In "hello" mỗi 5 giây
Bước 1: Tạo dự án
Xcode → Single View App → Tên: "HelloTutorialsPoint".
Bước 2: Tạo phương thức timer
Mở ViewController.swift, thêm method doSomething() dưới viewDidLoad:
private func doSomething() {
let timer = Timer.scheduledTimer(timeInterval: 5.0,
target: self,
selector: #selector(ViewController.hello),
userInfo: nil,
repeats: true)
}
Bước 3: Implement selector method
@objc func hello() {
print("hello")
}
Bước 4: Gọi trong viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
self.doSomething()
}
Mã hoàn chỉnh
import UIKit
class ViewController: UIViewController {
var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
startTimer()
}
func startTimer() {
// Hủy timer cũ nếu có
timer?.invalidate()
// Tạo timer mới
timer = Timer.scheduledTimer(timeInterval: 5.0,
target: self,
selector: #selector(hello),
userInfo: nil,
repeats: true)
}
@objc func hello() {
print("hello - \(Date())")
}
// Quan trọng: Hủy timer khi view controller bị hủy
deinit {
timer?.invalidate()
timer = nil
}
}
Kết quả
Console in ra "hello" mỗi 5 giây.

Các lưu ý quan trọng về Timer
| Vấn đề | Giải pháp |
|---|---|
| Retain cycle (memory leak) | Timer retain target (self). Dùng weak self trong closure-based timer hoặc invalidate trong deinit |
| Timer không chính xác | Timer không phải real-time, có độ trễ vài ms. Không dùng cho timing chính xác |
| Background | Timer bị tạm dừng khi app vào background (trừ khi có background task) |
| RunLoop | Timer gắn vào RunLoop.current. Nên chỉ định mode: .common cho UI responsive |
Cách hiện đại hơn: Closure-based Timer (iOS 10+)
timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { [weak self] _ in
self?.hello()
}
- Không cần
@objcvàselector - Dễ dàng capture
[weak self]tránh retain cycle - Code gọn gàng, Swifty hơn
DispatchSourceTimer (Hiệu năng cao, chính xác hơn)
let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
timer.schedule(deadline: .now(), repeating: 5.0)
timer.setEventHandler { [weak self] in
self?.hello()
}
timer.resume()
// Hủy: timer.cancel()
- Chạy trên background queue, không block main thread
- Độ chính xác cao hơn Timer truyền thống
- Phù hợp cho tác vụ nền, không cập nhật UI trực tiếp
Tóm tắt khi nào dùng cái nào
- Timer.scheduledTimer: Đơn giản, cập nhật UI, tác vụ nhẹ
- Closure-based Timer: Ưu tiên cho code Swift hiện đại
- DispatchSourceTimer: Background task, độ chính xác cao, high frequency
- CADisplayLink: Đồng bộ với refresh rate màn hình (60fps/120fps) - cho animation