Sometimes you want data or functionality to belong to a struct itself, not to any individual instance. That's what static properties and methods are forโlet's break them down with some examples!
Every property and method we've added to our structs so far has belonged to instances โ each Ninja you create has its own name, each Guild has its own gold. But sometimes you need data or functionality that belongs to the struct itself, shared across everything. That's where static comes in. ๐ฅ
The Problem Static Solves
Imagine we're building an anime series tracker app and we want to keep a count of how many series have been registered โ not on any one series, but across all of them:
struct AnimeSeries {
static var totalRegistered = 0
static func register(title: "String) {"
print("\(title) has been added to the tracker!")
totalRegistered += 1
}
}
Notice the static keyword on both the property and the method. This means they belong to AnimeSeries the type itself โ not to any specific instance.
Here's how you use them:
AnimeSeries.register(title: "\"Naruto\")"
AnimeSeries.register(title: "\"One Piece\")"
AnimeSeries.register(title: "\"Attack on Titan\")"
print(AnimeSeries.totalRegistered) // 3
No instance needed โ you call directly on AnimeSeries. That's the key difference: regular properties need an instance (var series = AnimeSeries()), static properties belong to the struct itself.
Why No mutating Keyword?
You might have noticed that register() modifies totalRegistered but isn't marked as mutating. That's because mutating is only needed for regular instance methods, to handle cases where the struct instance was created as a constant.
Static properties and methods don't belong to any instance, so there's no instance to be constant or variable โ mutating simply doesn't apply here.
self vs Self โ Two Different Things
Now that we have static members, there are two similar-looking keywords that mean very different things:
-
self(lowercase) โ refers to the current instance of the struct -
Self(uppercase) โ refers to the current type itself
struct Ninja {
var name: String
func introduce() {
print("I am \(self.name)") // self = this specific ninja
}
static func describe() {
print("We are all \(Self.self)s") // Self = the Ninja type
}
}
A helpful way to remember: Swift types always start with a capital letter (Int, String, Bool) โ and Self follows that same convention because it is a type.
Two Main Uses for Static
Use 1 โ Storing Shared App Data
Static properties are perfect for storing data that's the same everywhere in your app โ configuration, constants, shared settings:
struct AppConfig {
static let appVersion = "1.0.0"
static let maxEpisodesPerDay = 10
static let animeAPIBaseURL = "https://api.animelist.com"
}
Now anywhere in your app you need the version number or API URL, you just write AppConfig.appVersion or AppConfig.animeAPIBaseURL. No need to create an instance โ you just read it directly from the type.
This is cleaner and safer than defining these as loose global constants floating around your codebase.
Use 2 โ Example Instances for SwiftUI Previews
This one is especially useful in SwiftUI. When you're building a screen that displays a Ninja or an AnimeCharacter, SwiftUI lets you preview it in Xcode โ but you need some sample data to fill it with.
The cleanest way to provide that is with a static let example property:
struct AnimeCharacter {
let name: String
let show: String
let powerLevel: Int
static let example = AnimeCharacter(
name: "Goku",
show: "Dragon Ball Z",
powerLevel: 9001
)
}
Now whenever you need a sample character to pass into a SwiftUI preview, you just write AnimeCharacter.example. It's always available, always consistent, and you didn't need to create a new instance just to test your UI.
Mixing Static and Non-Static
You can have both static and regular members in the same struct โ but there are rules about how they interact:
From static code, you can't access non-static members:
struct AnimeSeries {
var title: String
static var totalRegistered = 0
static func showTitle() {
print(title) // โ Can't access โ which instance's title would this be?
}
}
This makes sense: if you're in static code, there's no specific instance to read from.
From non-static code, you can access static members using the type name:
struct AnimeSeries {
var title: String
static var totalRegistered = 0
func describe() {
print("\(title) โ Series #\(AnimeSeries.totalRegistered)") // โ
}
}
Combining Static with Private
You can also combine static with access control from the last article. For example, if you want a counter that's shared across all instances but can only be changed through a controlled method:
struct AnimeEpisodeTracker {
private static var episodesWatched = 0
static func watch() {
episodesWatched += 1
print("Episodes watched today: \(episodesWatched)")
}
static func totalWatched() -> Int {
episodesWatched
}
}
AnimeEpisodeTracker.watch() // "Episodes watched today: 1"
AnimeEpisodeTracker.watch() // "Episodes watched today: 2"
print(AnimeEpisodeTracker.totalWatched()) // 2
// AnimeEpisodeTracker.episodesWatched // โ private โ not accessible
The episodesWatched counter is shared across the entire app, but it's private so it can only be changed through watch().
A Quick Note on When to Use Static
Static properties and methods aren't something you'll reach for constantly โ most of the time, regular instance properties and methods are what you need. But they shine in a handful of situations:
- App-wide constants โ version numbers, API endpoints, configuration values
- Shared counters or state โ something that tracks across all instances
-
SwiftUI preview data โ
static let examplefor sample instances - Utility methods โ helper functions that don't need any instance data
Wrap Up
| Concept | What It Means |
|---|---|
static |
Belongs to the struct type itself, not to any instance |
| Static property | Shared across all instances โ accessed via the type name |
| Static method | Called on the type directly, no instance needed |
self |
The current instance |
Self |
The current type |
| Common uses | Shared app data, SwiftUI preview examples, utility methods |
This article was written by me; AI was used to improve grammar and readability.
Top comments (0)