Global variable
Essence
A global variable is declared at the top level of a file, outside any type or function, and is accessible from anywhere in the module (with public, from other modules too). Where exactly in the file it sits does not matter.
How globals work in Swift
- Lazy initialisation: a global in an ordinary file is initialised on first access, not at launch, and that is thread-safe (
swift_onceunder the hood, likedispatch_once). The exception is top-level code inmain.swiftand playgrounds: there variables are initialised in order, top to bottom. - Swift 6: a mutable global
varwithout isolation is a compile error ("global variable is not concurrency-safe"). Options: make it alet(of aSendabletype), isolate it with@MainActor, or take responsibility explicitly withnonisolated(unsafe).
import Foundation
// Initialised lazily on first access, thread-safe
let apiBase = URL(string: "https://api.example.com")!
// Swift 6: `var launchCount = 0` — error: global is not concurrency-safe
@MainActor var launchCount = 0 // main-actor access only
nonisolated(unsafe) var legacyFlag = false // "I handle the races myself"
@MainActor func appDidLaunch() { launchCount += 1 }
Why global state is considered bad practice
- A hidden dependency: a function reads a global and the signature does not show it — harder to test and reuse.
- Shared mutable state is a source of data races; Swift 6 forces you to deal with it explicitly.
- Initialisation order across modules is not under your control.
Alternatives: static let constants inside a namespace type (enum Config { static let apiBase = ... }), dependency injection, @Environment in SwiftUI, an actor for shared mutable state. A singleton (static let shared) is still a global, but at least with lazy initialisation and a namespace.
What the interviewer looks for
Do you know about lazy, thread-safe initialisation (the common question "why is static let shared thread-safe?") and what Swift 6 does with global vars.