Timer
Swift's Timer class lets you execute code after a delay or at regular intervals. It is commonly used for periodic UI updates and animation triggers.
Method List
| Method / Property | Description |
|---|---|
| Timer.scheduledTimer(withTimeInterval:repeats:block:) | Creates a timer and adds it to the default RunLoop. |
| Timer.scheduledTimer(timeInterval:target:selector:userInfo:repeats:) | Creates a timer using a selector (Objective-C style). |
| Timer.invalidate() | Stops the timer. It cannot be restarted. |
| timer.isValid | Returns whether the timer is still active. |
| timer.fire() | Fires the timer immediately. |
| Task.sleep(nanoseconds:) | Used for delayed execution in Swift Concurrency (recommended). |
Sample Code
import Foundation
// A timer that repeats every 1 second
var count = 0
let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
count += 1
print("Elapsed: \(count) second(s)")
if count >= 3 {
timer.invalidate() // Stop the timer
print("Timer stopped")
}
}
// Run the RunLoop to actually fire the timer (for command-line apps)
RunLoop.current.run(until: Date(timeIntervalSinceNow: 3.5))
// A one-shot timer that fires only once
let oneShot = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) { _ in
print("Fired once after 2 seconds")
}
RunLoop.current.run(until: Date(timeIntervalSinceNow: 2.5))
// Delayed execution with Swift Concurrency (recommended)
Task {
print("Task started")
try await Task.sleep(nanoseconds: 1_000_000_000) // Wait 1 second
print("Processing after 1 second")
try await Task.sleep(nanoseconds: 500_000_000) // Wait 0.5 seconds
print("Processing after another 0.5 seconds")
}
RunLoop.current.run(until: Date(timeIntervalSinceNow: 2.0))
Overview
Timer operates by being attached to a RunLoop. scheduledTimer is automatically added to the default RunLoop. When using a timer on a background thread, you must add it to a RunLoop manually.
In environments that support Swift Concurrency, using Task.sleep(nanoseconds:) or Task.sleep(for:) instead of Timer is simpler. If you forget to stop a Timer, the RunLoop will continue to hold a reference to it, causing a memory leak. Always call invalidate() when the timer is no longer needed.
For NotificationCenter, see NotificationCenter.
If you find any errors or copyright issues, please contact us.